Passing JVM opts to maven plugin - maven-plugin

I know that plugins like surefire have an "argLine" configuration parameter which they pass along to the JVM where the specific goals for the plugin is run. As I understand, by default, maven plugins are forked and run in a separate JVM (please correct me if I am wrong).
I am trying to figure out how to pass on VM arguments to a maven plugin jibx, but don't know if there is an easier/declarative way (or via a Util class) that I can configure it to do this. In surefire, there are utility classes in booterclient that seem to be handling this, but the functionality seems to be universal across plugins, right? Hence wondering if there might be some support from Mojo/Plexus to add this easily without writing a bunch of plumbing code. Again, please correct me if my understanding is incorrect
Thanks in advance!

The actual Maven plugin classes are run in the same JVM as Maven.
Where a Maven plugin is wrapping a separate tool, it depends on how the Maven plugin was written whether it forks a process or not.
For example the Cobertura Maven Plugin forks a process to do the Cobertura things. There is no technical reason for this fork, in the case of Cobertura the forking of the JVM is to work around the GPL licensing of the Cobertura Tool itself.
As you noticed the Surefire plugin usually forks a process for running the unit tests. It does not technically need to fork (see forkMode=never) however, there are good reasons due to the poor isolation of some parts of the JVM that require forking, e.g. System properties being global.
Looking at the plugin in your question you can see that it is just invoking the JIBX's main method directly. In other words it is not forking the JVM at all. If there are JVM options that you want, you will need to use the MAVEN_OPTS environment variable to specify them (with the side-effect that they are global for Maven, and if you forget to specify them, then things will not work as you expect)
I think to fix this you should really suggest a patch to the plugin that forks and accepts JVM options for the forked JVM

Related

.NET: How to isolate an anti-debugging class library?

I built a .NET class library and used an obfuscator to obfuscate it with anti-debugging.
I built a testing project using my obfuscated class library. I would have hoped that anti-debugging forbids debugger to step into my class library. But it simply threw exception "Debugger detected" when my class library was invoked when I started the project in debugging mode (by pressing "F5" in Visual Studio).
What this means is that if a project uses my library then the developer simply cannot debug at all. They may have millions of lines of code that has nothing to do with my library. Not being able to debug at all in their project will only mean one thing: they will not use my library.
Is there anyway a developer can do to "isolate" my library, so that they can debug elsewhere?
Specially thanks to #Artem Razin for:
isolate sensitive code to a separate process that runs with the
enabled anti-debugging feature.
Its great and helpful. Also virtualization he specified is good approach. I will post you a good approach if you need exactly working with anti-debug envirnoment. Bceause you mention the exception: Debugger Detected
Am assume you use Eziriz .NET Reactor. When I speak with support. They said you can't provide two anti-debug version for specific HardwareID. Because HardwareID involved in the licensing system and it must not bypassed!
I can tell you a workaround for that by using .NET Reactor CLI and MSBuild targets.
What scenario it should be? (I will show what we need to do before write CLI...)
If you a have a developer team, or friend who need to use your obfuscated library. That's great. But he can't debug because its anti-debugged.
Then we must separate an assembly into two assemblies. One for developer its obfuscated but without anti-debug feature enabled. and other assembly into release folder for consumer or your audience.
So when you build your assembly. or need to create nuget package for it. you need to do a double obfuscation. Firstly you will obfuscate the anti-debug version for consumer into Consumer/AntiDebug folder. Secondly you will obfuscate the original DLL again but for developer without anti-debug feature!
So please use Directory.Build.targets for that. Here's code for obfuscation:
<Target Name="ObfuscateDLL" Condition="'$(Configuration)' == 'Release' AND $(OutputType) == 'Library'"
AfterTargets="AfterBuild">
<PropertyGroup>
<ObfuscatedFolder>$(MSBuildThisFileDirectory)\Anti Debug</ObfuscatedFolder>
<ObfuscatorPath>C:\Program Files (x86)\Eziriz\.NET Reactor\dotNET_Reactor.Console.exe</ObfuscatorPath>
<ObfuscatorParameters>-antitamp 1 -anti_debug 1 -hide_calls 1 -hide_calls_internals 1 -control_flow_obfuscation 1 -flow_level 9 -resourceencryption 1 -antistrong 1 -virtualization 1 -necrobit 1 -mapping_file 1 -mapping_file_overwrite 1 -mapping_filename "<ProtectedAssemblyLocation>\<AssemblyName>.nrmap" </ObfuscatorParameters>
</PropertyGroup>
<!-- Obfuscate with anti-debug to Obfuscated folder or \Release path when GenerateNuget enabled -->
<Exec Command=""$(ObfuscatorPath)" -file "$(TargetPath)" -targetfile "$(ObfuscatedFolder)\$(TargetFileName)" $(ObfuscatorParameters)"/>
<!-- Obfuscate without anti-debug to /Release path for Nuget package for Developers -->
<Exec Command=""$(ObfuscatorPath)" -file "$(TargetPath)" -targetfile "$(TargetPath)" $(ObfuscatorParameters.Replace('-anti_debug 1','').Replace('-mapping_file 1', ''))"/>
</Target>
Please use above code! if you need it as simple as possible. But you need to manually create nuget package for you developer. via MSBuild or by the way you need.
But If you use .NET Framework and want to generate obfuscated debuggable nuget package (for developers). And also provide anti-debug version to your consumer. You can use following MSBuild targets.
It contains ability to create Nuget package with all dependencies automatically.
It obfuscate the consumer library to Anti Debug folder. then It will obfuscate nuget version and packacking it. then copy back Anti Debug version to Release folder.
You can manually turn on/off GenerateNuget property. If you will not generate nuget so anti-debug version only produced.
Change the code depending on your needs...
https://pastebin.com/wmvcWMUp
(See link XML content are large can't posted to StackOverflow)
Anti-debugging is a well-known feature since the times of exe packers. Unfortunately, it is a process-wide thing. Usually, .NET obfuscators check debugger-specific environment variables.
There is no way to prevent a debugger from stepping into your assembly.
I would say that anti-debugging is for those who want to protect their end-user products, not libraries.
You can virtualize your code (modern obfuscators like ArmDot provide this feature), so debugging it would have almost no sense.
Another idea is to isolate sensitive code to a separate process that runs with the enabled anti-debugging feature. On the client-side, you just provide a proxy that redirects all calls to the process.

Codenamone One Online Build Failure

We added new features to our data collection mobile application after two -three months of inactivity, only for the build to keep failing.
This is the stack trace
ll-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
This is often due to inadvertently including a core library file
in your application's project, when using an IDE (such as
Eclipse). If you are sure you're not intentionally defining a
core class, then this is the most likely explanation of what's
going on.
However, you might actually be trying to define a class in a core
namespace, the source of which you may have taken, for example,
from a non-Android virtual machine project. This will most
assuredly not work. At a minimum, it jeopardizes the
compatibility of your app with future versions of the platform.
It is also often of questionable legality.
If you really intend to build a core library -- which is only
appropriate as part of creating a full virtual machine
distribution, as opposed to compiling an application -- then use
the "--core-library" option to suppress this error message.
If you go ahead and use "--core-library" but are in fact
building an application, then be forewarned that your application
will still fail to build or run, at some point. Please be
prepared for angry customers who find, for example, that your
application ceases to function once they upgrade their operating
system. You will be to blame for this problem.
If you are legitimately using some code that happens to be in a
core package, then the easiest safe alternative you have is to
repackage that code. That is, move the classes in question into
your own package namespace. This means that they will never be in
conflict with core system classes. JarJar is a tool that may help
you in this endeavor. If you find that you cannot do this, then
that is an indication that the path you are on will ultimately
lead to pain, suffering, grief, and lamentation.
1 error; aborting
:transformClassesWithDexForRelease FAILED
:transformClassesWithDexForRelease (Thread[Daemon worker,5,main]) completed. Took 11.045 secs.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':transformClassesWithDexForRelease'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException: Error while executing java process with main class com.android.dx.command.Main with arguments {--dex --verbose --force-jumbo --num-threads=4 --output /tmp/build8570106392456281219xxx/Application/build/intermediates/transforms/dex/release/0 --min-sdk-version 15 /tmp/build8570106392456281219xxx/Application/build/intermediates/transforms/proguard/release/0.jar}
You or one of the cn1libs you are using included a javax.xml package as part of the code. We migrated to build target 27 over the weekend and I'm guessing that Google made checks for this sort of problem more rigid.
I see a lot of keep statements in your build hints so I'm guessing this was done intentionally.

Using nix in a continuous delivery workflow

Can nix be used in a continuous-delivery workflow?
We're using semaphore as our continuous integration service, and now I'm looking into building packages upon a successful build. For this I'm considering using nix.
I don't know what would be the right way of setting up a continuous delivery pipeline with this package manager. It seems that such an automated process would involve:
Making a branch of the nixpkgs repository (in the CI server).
Updating the rev field of fetchFromGithub.
(automatically) submitting a pull-request.
But I don't know if this makes sense, and also I'm concerned that the continuous-delivery process involved a manual step (having an human aproving the pull-request).
Can nix be used in a continuous-delivery workflow?
Yes. It's typically done with Hydra, a CI system built with Nix. But, it may be possible to do this with Semaphore.
Semaphore CI provides build environments that are language specific, but... it's running Ubuntu, so theoretically you can do something like this:
Install Nix as if it were a dependency. See this article.
Add your Nix package, which I suppose you can do with Git. You don't really need to clone Nixpkgs.
Use nix-build to build your package. This will create a result symbolic link to the build output.
Deploy using git-deploy.
If you do something like this with your package you can call it directly from nix-build because you won't have to provide the package dependencies as arguments:
{ pkgs ? import <nixpkgs> {} }:
let
stdenv = pkgs.stdenv;
...
in
stdenv.mkDerivation {
..
}
Optimization
Installing Nix for every build is wasteful, but perhaps you can cache the Nix store. See this article.

Is there any Apache shutdown hook to be used for cleanup?

I am currently developing a module for Apache 2/2.2 and need to perform some cleanup before the main Apache process terminates (not the child processes).
I have searched extensively without finding any guidelines on which hook to use. Can anyone help point me in the right direction?
I'm not sure what you are exactly trying to do, but I think that the apr_reslist_create and apr_pool_cleanup_register functions may help you. One of the parameters in the apr_reslist_create function is apr_reslist_destructor which you can use to pass destructor function. Also, I think you should take a look at the mod_dbd module source code since it is a pretty good example of how to create and cleanup external resources from the apache process.
Apr-Util apr_reslist_create
Apr apr_pool_cleanup_register

How to check JRE version prior to launch?

What's the best way to determine if the version of the JRE installed on a machine is high enough for the application which the user wants to run? Is there a way of doing it using java-only stuff? I'd like the solution to work on Windows/Linux/MacOSX - if the JRE version is too low a message should be displayed. Currently I'm getting an exception if i try to run it on Java 1.5 (the app is built for Java 1.6). If there's no universal solution, what's the best way to do it on Windows?
You could do this using reflection and two compilers. Compile a main class with the oldest java version you want to be able to run at all with. It checks the version using System.getProperty("java.version"), or whatever, and then uses reflection to load your real main class if that check passes, possibly even loading the jar directly. The JRE shouldn't load any classes that weren't referenced by your outer main class at compile time.
You might consider Java Webstart. Even if the name implies something like applets, it's about standalone-applications. Webstart is a launcher, that checks a JNLP-file (a simple XML-file, where you configure the download-location of your app, the needed Java-version and some other metadata) and starts your app with the correct JRE. It even updates the application, if a newer version is available. The downside is, you have to write a JNLP-file. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<!--
###############################################################################
#
# #(#)draw.jnlp 1.6 02/09/11
#
# JNLP File for Draw Demo Application
#
###############################################################################
-->
<jnlp spec="0.2 1.0"
codebase="http://java.sun.com/javase/technologies/desktop/javawebstart/apps"
href="draw.jnlp">
<information>
<title>Draw 4 App</title>
<vendor>Sun Microsystems, Inc.</vendor>
<homepage href="http://java.sun.com/javase/technologies/desktop/javawebstart/demos.html"/>
<description>A minimalist drawing application along the lines of Illustrator</description>
<description kind="short">Draw Demo Short Description</description>
<icon href="images/draw.jpg"/>
<offline-allowed/>
</information>
<resources>
<j2se version="1.3+" href="http://java.sun.com/products/autodl/j2se"/>
<j2se version="1.3+"/>
<jar href="draw.jar" main="true" download="eager"/>
</resources>
<application-desc main-class="Draw"/>
</jnlp>
A second possibility is to use a launcher-program. An example is the Apache Commons Launcher. You can also write some launcher app yourself, but that's usually not worth the effort.
You might also consider using Commons-Launcher, which allows you to setup various environment settings, or perform pre-checks before calling your application.
http://commons.apache.org/launcher
Generally, we've approached this with a C or (when unix-only) shell wrapper. Not sure this will really work for you.
We also approach this by embedding the JRE in our product. Takes care of 99.9% of the cases (the other 0.1% of the time is a user explicitly changing our configuration to use a different JVM). Again, not sure that this is a reasonable solution for you.
In our case, there is significant amounts of native code (JNI and otherwise), so tailoring an installable image for each platform we support is required anyway. But if you're dealing with a pure-Java solution, you may simply have to document your minimum and tell people to get with the program (no pun intended) if they're to run your stuff. It's sorta like people complaining that my Mac won't run MSVC, or that my Linux box is having problems running World of Warcraft. That's just not the (virtual) machine the software is targeted for - you need to switch. At least in the Java world, we really can call this an upgrade, though, without hurting anyone's OS-religious feelings. (Try telling the Mac user to "upgrade" to Windows XP to run MSVC - there's a beat-down waiting to happen.)
You can require a Java version when running the Java command, e.g. java -version:1.6* com.me.MyClass. Not sure if this works on all releases of Java, but it works OK on 1.6 anyway.
An application built for a higher-version JRE will not run on a lower-version JRE. So you wouldn't be able to just add code to your application to check the JRE version - if the JRE version was incompatible, your JRE-version-checking code would not run in the first place.
What you'd have to do is have some sort of launcher application that is built for a lower-version JRE (1.3?) that checks the version and then launches your app if necessary. This sounds kind of kludgy to me.
What about checking the version during installation? Are you installing the app in a way that allows you to check environment variables, or do any sort of scripting?
For the launcher - Check the version in there.
Inside the APP; as above use System.getProperties();
Properties sProp = java.lang.System.getProperties();
String sVersion = sProp.getProperty("java.version");
sVersion = sVersion.substring(0, 3);
Float f = Float.valueOf(sVersion);
if (f.floatValue() < (float) 1.4) {
System.out.println("Java version too low ....");
System.exit(1);
}
...
Have a launching class compiled for Java 1.2 which invokes the real main() in your 1.6 classes. If an unsupported class exception is thrown them catch it and display a nice error message.
Here is the code to get the JRE version installed in a system.
var list = deployJava.getJREs();
var result = "";
result = list[0];
for (var i=1; i<list.length; i++)
{
result += ", " + list[i];
}
document.write("jre version : "+result);
System.getProperties() gives you a listing of JVM properties including the different version ids of the JRE, JVM and specification. This implemented for all versions of Java so should work regardless of version compiled in and version run in, or the implementation.
If you write a basic class to test the version, you can call this first in your main() launching class. It must really be basic functionality though or you might risk breaking it.
Hmm .. call me a boring guy, but what's wrong with using Launch4J or any other native launcher, for instance.
Use a native launcher to check the JVM version before actually running your code. Java only solutions (in my book) only make sense when you deal with developers; once you hit end-users, you'll realize that they dont care about Java or its technical details at all. If you would have written your application in GW-Basic they would not care less as long as your application works.
If Java 1.6 is not installed, lauchner4j will point the user to the download page for JDK 1.6. Thats probably more suitable for your problem than doing magic in Java.
I find that WinRun4J works quite well for me (but then again I may be biased since I wrote it:-)). This lets you specify a minimum and/or maximum version of java allowed. It will pop up a message box to the user if a suitable JRE version is not found (and the message is customisable).
All those above is too damn complicated.
Just go:
Properties props = System.getProperties()
props.list(System.out)
And you will see everything about your JVM, JRE, JDK and staff.
Or get a specific value by using:
//full list of possible props you can see if u run code above
String props = System.getProperty(prop)

Resources