Pass command-line argument javaagent with maven exec plugin - java

I have a caching app in Java and I need to put objects of different size in cache. The problem is that I didn't really know how to count the size of a custom object and I've found the solution - to use the library: http://mvnrepository.com/artifact/com.googlecode.sizeofag/sizeofag/1.0.0.
To run the program using the library I need to specify command-line argument -javaagent. So, how can I do it if I'm using maven???
The program is simple:
protected static Boolean b;
public static void main( String[] args )
{
System.out.println(SizeOfAgent.sizeOf(b));
}
This is the output:
0
Can not access instrumentation environment.
Please check if jar file containing SizeOfAgent class is
specified in the java's "-javaagent" command line argument.
P.S. I know, that such kind of question already exists, but it has no proper answer.

On a Linux/Unix machine the "mvn" command will use a shell variable "MAVEN_OPTS" to pass in options. This is useful if you want to give Maven more memory. In your .profile or .bash_profile put a line like this in:
export MAVEN_OPTS=-javaagent
On windows:
in shell (cmd.exe) type "set MAVEN_OPTS=..."
or
add MAVEN_OPTS to your environment
On NetBeans:
In ~/.netbeans/6.5/, create etc/netbeans.conf. Add your environment variables there, e.g.:
export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=128m"

Related

run existing java program with cmd

I have a running java program which converts a json file into another file format. Everything works great.
For the implementation I decided to use the MVC pattern.
Now I want to implement the whole conversion routine so that I can use a command prompt but I never worked with that and don't know how to achieve this at all.
My thoughts were:
Open cmd and navigate to the main.java-file.
Print out the whole possibilities (the user should be able to enter the dir of the source file and the target dir, the user should be able to choose the target format).
If everything has been entered by the user, the conversion routine should be started by pushing ENTER.
Help would be really nice. For the moment I just know how to compile (javac helloWorld.java) and print "Hello World!" by exeuting a program with java helloWorld...
The apache commons cli project provides utilities for parsing command line arguments and providing help menu. This makes it pretty simple to handle the args provided to your main method.
You will also need to provide scripts to assemble your class path. You can look at the maven app assembler plugin for ways of doing this.
The interaction between a shell/command prompt and the started Java program is very similar to the way it works in C programs*. The main() method receives arguments as strings from the command line (or from any other parent process which executes the java runtime).
In Java you get an array of strings. You need to decide yourself which string has what meaning.
public static void main(String[] arg) { // traditional or String ... args
System.out.println("You have " + arg.length + " arguments);
if (arg.length >= 1) System.out.println("First: " + arg[0]);
}
When starting a Java runtime with arguments, it is important to note, that arguments start after the class name (or the JAR name):
java -cp . package.Main arg0 arg1 ...
java -jar package.jar arg0 arg1 ...
The Java runtime also has an mechanism to specify system properties on the command line. This is done with the -D option.
java -Dverbose=yes -jar package.jar arg0 arg1 ...
java -jar package.jar -Dverbose=yes arg1 ... //not a system property but arg[0]
It is important, that this option is specified before the class/jar-name, otherwise it will not be processed by the runtime, but you will see another argument.
String verbose = System.getProperty("verbose", "false");
The reason why system properties are useful: you can use them for optional control, so you do not have to worry about recognizing arguments (there are a number of libraries out there which can do that but for small tools I think it is overkill).
BTW: there are some interactions between shells/prompts and started programs when using wildcards (* and ?) and whitespace/quoting - those are OS specific.
* in C the first argument args[0] is the program name, in java arg[0] is the first argument after the class name.

Pass JAVA HOME as parameter to mvn

I would like to know if it is possible to pass JAVA_HOME as parameter to mvn command line. I have searched almost everywhere, but couldn't find an answer to that.
I know we can set JAVA_HOME using export, but I need to pass it as parameter if that is possible. Something like:
mvn install -DJava_Home=/usr/java/jdk-1.7.0
Another hacky way I did this: ( I have most of my projects on Java 7, but a handful on java 8 )
1) Add a new env variable JAVA8_HOME to your .zshrc ( or similar )
2) copy the 'mvn' executable and call it 'mvn8'
3) Replace 'JAVA_HOME' with 'JAVA8_HOME' in 'mvn8'
Now, mvn8 clean install should just work.
no, not directly, but looking at mvn.bat on my machine i see this promising snippet:
#REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
so you could override any variable you like in a mavenrc_pre script file, although i realize this wont let you override java home from the command line.
worst case, mvn is a simple script file and you could add the option to it. also note that simply overriding JAVA_HOME may not always produce the expected results as on many systems JAVA_HOME\bin is on the path. this means that even if you override it the previous jvm will still be on the path, which might lead to unexpected results.

How to set a unix dynamic library path (LD_LIBRARY_PATH) in Java?

I have a binary executable (no source code) which requires this command to be executed in the terminal - export LD_LIBRARY_PATH = "" to link to a library lbtiff.so.3 which I have in a directory. Only after I execute this export command, I can execute the binary, otherwise it gives an error - "error while loading shared libraries: libtiff.so.3...
Now, I want to execute this binary from my java code. But simply executing the export command in the runtime does not do anything and the "error while .." error still occurs when I execute the binary from Java. I guess setting the unix specific environment variable LD_LIBRARY_PATH might not be possible from Java - is there a way I can run my binary from Java and it is able to find the libraries? Here's my current code -
Process p = Runtime.getRuntime().exec("bash -c export LD_LIBRARY_PATH=<lib path>");
p = Runtime.getRuntime().exec("<binary path>");
Rather than Runtime.exec, use ProcessBuilder. That will allow you to specify environment variables when you run the binary that requires them
ProcessBuilder pb = new ProcessBuilder("<binarypath>");
pb.environment().put("LD_LIBRARY_PATH", "<libPath>");
Process p = pb.start();
Your approach with two separate Runtime.exec calls will not work, because the environment settings you make in the first one only affect that particular Process, not subsequent processes started by a separate invocation of Runtime.exec.
See my answer to another question. The best way is to not use an external shell to set the environment variable (your code doesn't work because it will not set the variable globally, only for the bash process), but to set the variable from within Java. Much easier and it works (and on all platforms, regardless of which shell is installed).
On unix systems you can prepend the variable before executing the command
LD_LIBRARY_PATH=... foo args
Will execute the program foo with args using the modified LD_LIBRARY_PATH
Or you could take advantage of the subshell by using:
(export LD_LIBRARY_PATH=...; foo args)

Giving environment variables as arguments

I have a jar file that gets arguments from commandline and I want to give parameter that contains environment variable. Something like below:
java -jar MyDev.jar -f %PROJECT_HOME%/src/test
But in above case program creates a directory named %PROJECT_HOME% however I want that PROJECT_HOME value in system is /home/jack path. And program should follow /home/jack/src/test not %PROJECT_HOME%/src/test path.
How can I do that ?
Are you running this in a Unix shell? If so, I suspect you just want:
java -jar MyDev.jar -f ${PROJECT_HOME}/src/test
Using % is the Windows way of specifying environment variables - which doesn't appear to fit with a home directory of /home/jack...
The component responsible for environment variables substitution is the shell/command line processor (cmd.exe on Windows).
I wrote the following main method:
public static void main(String[] args) {
System.out.println(args[0]);
}
When I pass "%PATH%" as an argument, running it from within Eclipse prints out %PATH%. Running it from the command line prints out the actual path environment variable.
Note that you can access environment variables from your Java code by using System.getenv().
For example, System.out.println(System.getenv("PATH")) prints out the actual path variable both from Eclipse and from the command line.
One very likely cause for this could be that the variable PROJECT_HOME is not defined or has a misspelled name. Hence, unless you have already done so, you should do echo %PROJECT_HOME% right before you start the java program in order to ensure that the variable is defined.

Setting lucene jar files in java classpath

I'm new to lucene and is having trouble getting started.
Following the beginners guide at http://lucene.apache.org/java/3_3_0/demo.html i'm trying to set the classpath, copying the syntax from http://download.oracle.com/javase/1.3/docs/tooldocs/win32/classpath.html.
this is what I entered in the command line:
C:\Users\k>java -classpath C:\Users\k\Downloads\lucene-3.3.0\contrib\demo\lucene-demo-3.3.0.jar;C:\Users\k\Downloads\lucene-3.3.0\lucene-core-3.3.0.jar
It returns a list of options usable with the java keyword.
What am i doing wrong ?
You need something along the lines of
C:\Users\k>java -classpath C:\Users\k\Downloads\lucene-3.3.0\contrib\demo\lucene-demo-3.3.0.jar;C:\Users\k\Downloads\lucene-3.3.0\lucene-core-3.3.0.jar org.apache.lucene.demo.IndexFiles -docs {path-to-lucene}/src
It looks like you set the classpath correctly, all you needed to do after that was org.apache.lucene.demo.IndexFiles which tells the JVM which is the main class of the application and -docs {path-to-lucene}/src is an argument passed into the lucene demo.
The command you are using is not for setting class path. It is the java command used to run java class file. You are providing it a class path arguments which determines from where to load class files.
To set classpath use this command on windows:
set CLASSPATH=classpath1;classpath2...
So if you want to still use java command with -classpath argument then specify a class name at the end of command which is the class going to be run like
C:\Users\k>java -classpath C:\Users\k\Downloads\lucene-3.3.0\contrib\demo
\lucene-demo-3.3.0.jar;C:\Users\k\Downloads\lucene-3.3.0\
lucene-core-3.3.0.jar MyClassName

Categories

Resources