ow do you run your non-webapp maven-based java program from command line? One might be using exec:java route and specify the main class. The only sticking point here is that the classpath will be filled with references to the user’s local repository (usually NFS mounted). I would be much more comfortable if I had all the set of jars that I would be dependent on packaged WAR-style and be ready at my disposal. In that sense, the application would be much more self-contained. It also becomes that much easy for someone to testdrive your application. Hence the concept of an “uber” jar – a unified jar that will house all classes/resources of the project along with classes/resources of its transitive dependencies.
Showing posts with label maven. Show all posts
Showing posts with label maven. Show all posts
Monday, May 27, 2013
Monday, October 29, 2012
Classpath of a running java process spawned via maven exec:java
Ran into a peculiar situation where I was using the maven exec:java plugin to launch a java process. The plugin does the heavy lifting of creating the correct classpath comprising of its dependencies (much like what JUnit does). In this case, I suspected the java and maven to be conspiring against me by picking up a staler jar. In the case of Tomcat (or other containers) it is usually easy to look at WEB-INF/lib for the jars that will be used. But in this case, the command line didn't yield much information.
The -classpath /tools/maven/boot/plexus-classworlds-2.4.jar didn't help much here. In JUnit, a whole file is created with the list of jars being used and it is very easy to inspect. There are intrusive ways to print the classpath for a application by either 1. setting -verbose:class when starting the process or by explicitly requesting in code with the system property "java.class.path". I fired up JVisualVM to see if it can help me examine the system property non-instrusively (since I really didn't want to restart the application for investigative reasons -- just yet). Again it showed the /tools/maven/boot/plexus-classworlds-2.4.jar as the value. That's when I came across this alternate way where you use the lsof command to see which files are open. Since the classloader has to refer to the JAR from where the class is being loaded, it shows up in the list of open files - however not sure if this is a sureshot way to get things done - what if the JVM decides to close off the connection to the JAR as a way of reducing number of open file descriptors.
References:
1. http://thilinamb.wordpress.com/2009/07/01/analyse-the-classpath-of-a-running-java-program/
> ps -ef | grep produser| grep java munshi 953 27405 0 01:21 pts/0 00:00:00 grep java munshi 31771 31758 11 01:14 pts/0 00:00:50 /usr/local/java/jdk/bin/java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8765,suspend=n -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8219 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -classpath /tools/apache/maven/boot/plexus-classworlds-2.4.jar -Dclassworlds.conf=/tools/apache/maven/bin/m2.conf -Dmaven.home=/tools/apache/maven org.codehaus.plexus.classworlds.launcher.Launcher --settings /u/produser/.m2/settings.xml clean compile exec:java -Dexec.mainClass=com.kilo.DriverCLI -Dexec.args=SOMETHING
The -classpath /tools/maven/boot/plexus-classworlds-2.4.jar didn't help much here. In JUnit, a whole file is created with the list of jars being used and it is very easy to inspect. There are intrusive ways to print the classpath for a application by either 1. setting -verbose:class when starting the process or by explicitly requesting in code with the system property "java.class.path". I fired up JVisualVM to see if it can help me examine the system property non-instrusively (since I really didn't want to restart the application for investigative reasons -- just yet). Again it showed the /tools/maven/boot/plexus-classworlds-2.4.jar as the value. That's when I came across this alternate way where you use the lsof command to see which files are open. Since the classloader has to refer to the JAR from where the class is being loaded, it shows up in the list of open files - however not sure if this is a sureshot way to get things done - what if the JVM decides to close off the connection to the JAR as a way of reducing number of open file descriptors.
> lsof -p 31771 | less COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 31771 produser cwd DIR 0,70 4096 13085795 /u/produser/testproject (filer.kilo.com:/vol/proj1/proj-302) java 31771 produser rtd DIR 253,0 4096 2 / java 31771 produser txt REG 253,0 7630 1465254 /usr/local/java/jdk1.7.0.04/bin/java java 31771 produser mem REG 253,0 156872 1441803 /lib64/ld-2.12.so java 31771 produser mem REG 253,0 1922112 1441807 /lib64/libc-2.12.so java 31771 produser mem REG 253,0 22536 1444029 /lib64/libdl-2.12.so java 31771 produser mem REG 253,0 145720 1441859 /lib64/libpthread-2.12.so java 31771 produser mem REG 253,0 598800 1444297 /lib64/libm-2.12.so java 31771 produser mem REG 253,0 47064 1441866 /lib64/librt-2.12.so java 31771 produser mem REG 253,0 113952 1444031 /lib64/libresolv-2.12.so java 31771 produser mem REG 253,0 124624 1444032 /lib64/libselinux.so.1 java 31771 produser mem REG 253,0 17256 1444294 /lib64/libcom_err.so.2.1 java 31771 produser mem REG 253,0 12592 1444030 /lib64/libkeyutils.so.1.3 java 31771 produser mem REG 253,0 915104 1444295 /lib64/libkrb5.so.3.3 java 31771 produser mem REG 253,0 43304 1444292 /lib64/libkrb5support.so.0.1 java 31771 produser mem REG 253,0 181608 1444293 /lib64/libk5crypto.so.3.1 java 31771 produser mem REG 253,0 268944 1444296 /lib64/libgssapi_krb5.so.2.2 java 31771 produser mem REG 253,0 6398 1361340 /usr/local/java/jdk1.7.0.04/jre/lib/amd64/librmi.so java 31771 produser mem REG 253,0 1023488 1361282 /usr/local/java/jdk1.7.0.04/jre/lib/ext/localedata.jar java 31771 produser mem REG 253,0 2476995 1361287 /usr/local/java/jdk1.7.0.04/jre/lib/resources.jar java 31771 produser mem REG 253,0 8934 1361283 /usr/local/java/jdk1.7.0.04/jre/lib/ext/dnsns.jar java 31771 produser mem REG 0,71 1501575 1312261 /u/produser/.m2/repository/com/google/guava/guava/10.0.1/guava-10.0.1.jar (filer.kilo.com:/vol/home2/produser)
References:
1. http://thilinamb.wordpress.com/2009/07/01/analyse-the-classpath-of-a-running-java-program/
Tuesday, September 11, 2012
Maven release plugin on a multi-module project having different releasecycles and hence versions
With Git migration headed in our direction, we were testing the readiness of our utility scripts for this new SCM. The maven-release-plugin had advertised that it supports git as a SCM and we were hoping that it would be straight-forward.
The project structure was like
We modified the parent pom file of parent as
FTR, the connection tag is the read link and the developerConnection is the read-write link. This is supported for cases where one may allow the reads and writes to happen via different transports - say HTTP for reads and only SSH for writes.
Also, the maven-release-plugin v 2.3.2 fixes some significant bugs, so make sure that you use this version of the plugin. Best set it up via pluginManagement.
We follow the standard pattern of moving changes from trunk -> branch -> tag in the SVN world.
With the move to Git, the tag is a real tag and is really a read-only point in the history of the project and hence no need to have commit hooks that were added to support the notion on tags in the SVN world. Other open source projects like Spring, Sonatype have adopted a similar approach.
Now comes the interesting part of doing a minor release for one of the sub-modules - say child2. With the regular invocation of the maven release:branch, it was complaining of an invalid git location as
Clearly, this was not a valid git location. I finally stumbled on this SO question which discusses that this is actually some intelligence on the part of the maven release plugin when it encounters multiple projects. So, the workaround? We just need to redefine the scm tags in the individual sub-modules again and voila - you are done!
Yes, this was a long winding rant, but hopefully someone will benefit from it!
The project structure was like
- parent
- child1
- child2
- child3
We modified the parent pom file of parent as
<scm> <connection>scm:git:ssh://gitserve/test/parent.git</connection> <developerConnection>scm:git:ssh://gitserve/test/parent.git</developerConnection> <url>http://gitweb/?p=test/parent.git;a=summary</url> </scm>
FTR, the connection tag is the read link and the developerConnection is the read-write link. This is supported for cases where one may allow the reads and writes to happen via different transports - say HTTP for reads and only SSH for writes.
Also, the maven-release-plugin v 2.3.2 fixes some significant bugs, so make sure that you use this version of the plugin. Best set it up via pluginManagement.
We follow the standard pattern of moving changes from trunk -> branch -> tag in the SVN world.
With the move to Git, the tag is a real tag and is really a read-only point in the history of the project and hence no need to have commit hooks that were added to support the notion on tags in the SVN world. Other open source projects like Spring, Sonatype have adopted a similar approach.
ssh://gitserve/test/parent.git/child2
Clearly, this was not a valid git location. I finally stumbled on this SO question which discusses that this is actually some intelligence on the part of the maven release plugin when it encounters multiple projects. So, the workaround? We just need to redefine the scm tags in the individual sub-modules again and voila - you are done!
Yes, this was a long winding rant, but hopefully someone will benefit from it!
Subscribe to:
Posts (Atom)