Table of Contents
Java Tips
This page is a none-organized list of tips, mostly for the errors I encountered with Java programming and the trouble shooting.
Unsupported major.minor version 51.0
During compilation of Java program, I encountered this error message. The reason was pretty straight forward: when the program that is being compiled is referring to a library or jar file that was compiled using different JRE version, this message appears.
To overcome this error, simple re-compile all the jar files by a consistent JAVA version.
java.lang.SecurityException – signer information does not match signer information of other classes in the same package
I encountered this message when there is a conflict by having two same jar files in the class path. Removing one of them should over come this error. There seems to be more to it as an explanation, and for that refer to this page or the quote below.
This happens when classes belonging to the same package are loaded from different JAR files, and those JAR files have signatures signed with different certificates - or, perhaps more often, at least one is signed and one or more others are not (which includes classes loaded from directories since those AFAIK cannot be signed).
So either make sure all JARs (or at least those which contain classes from the same packages) are signed using the same certificate, or remove the signatures from the manifest of JAR files with overlapping packages.
Extract compiler version from a class file
Sometimes you want to know the version of Java compiler used for a certain class. Then do the following.
javap -verbose MyClass
There will be then a line “major version XX” at the beginning of the output. Below is the list of correspondence between Java version and “major version”.
It might be better to add head command since the version number appears at the beginning.
javap -verbose MyClass | head
Java 1.2 uses major version 46
Java 1.3 uses major version 47
Java 1.4 uses major version 48
Java 5 uses major version 49
Java 6 uses major version 50
Java 7 uses major version 51
JAR file
For directly accessing a jar file and get build environment for that jar file, following is an example jython code.
from java.util.jar import JarFile #from java.util.jar import Manifest def printClasses(jf): for e in jf.entries(): print e.getName() def printManifest(jf): mf = jf.getManifest() if mf is not None: mainatt = mf.getMainAttributes() keys = mainatt.keySet() for i in keys: print i, mainatt.getValue(i) else: print 'pity, No Manifest File found!' # main filepath = 'D:\\gitrepo\\CorrectBleach\\CorrectBleach_.jar' filepath = 'C:\\ImageJ2\\plugins\\CLI_.jar' filepath = 'C:\\ImageJ2\\plugins\\AutoThresholdAdjuster3D_.jar' jf = JarFile(filepath) printManifest(jf)
Currently Running Java
To know the version properties of currently running Java, see the following jython example:
>>>> print System.getProperty('java.runtime.version') 1.6.0_20-b02 >>>> print System.getProperty('java.vm.version') 16.3-b01
Searching Jar files containing a specific class
Sometimes, from a huge number of jar files, you need to find a jar file that contains a class that you want to use. There is no trick, but to use command line tools. Listing classes in a jar file is not so difficult, as you could do
jar -tvf file.jar
But you could not do that to 50 files… Here is an one-liner that could be used: in this example, I was looking for a jar file that contains class 'CSVReader'.
find . -iname '*.jar' | while read JARF; do jar tvf $JARF | grep CSVRead.class && echo $JARF ; done
Quick Check of text file content within Jar file
To list the content of JAR file,
jar tvf myplugin.jar
will print out the list of files such as
0 Mon Apr 16 09:48:28 CEST 2012 META-INF/ 124 Mon Apr 16 09:48:26 CEST 2012 META-INF/MANIFEST.MF 103 Fri Feb 17 11:51:58 CET 2012 plugins.config 0 Fri Feb 17 11:51:58 CET 2012 emblcmci/ 4446 Fri Feb 17 11:51:58 CET 2012 emblcmci/BleachCorrection.java 6413 Fri Apr 13 16:15:00 CEST 2012 emblcmci/BleachCorrection_ExpoFit.java 4397 Fri Apr 13 16:17:10 CEST 2012 emblcmci/BleachCorrection_MH.java 4866 Fri Apr 13 16:18:24 CEST 2012 emblcmci/BleachCorrection_SimpleRatio.java 0 Fri Feb 17 11:51:58 CET 2012 histogram2/ 1499 Fri Apr 13 16:19:06 CEST 2012 histogram2/HistogramMatcher.java 2707 Fri Feb 17 11:51:58 CET 2012 histogram2/HistogramPlot.java 2043 Fri Apr 13 16:19:34 CEST 2012 histogram2/PiecewiseLinearCdf.java 2541 Fri Apr 13 16:19:26 CEST 2012 histogram2/Util.java
Since jar archive compression format is same as ZIP, you could also use unzip to list the files.
unzip -l myplugin.jar
unzip is a bit more convenient if you want to read out the content of text file within (eg plugins.config)
unzip -p myplugin.jar plugins.config
This will print out for example
# Author: Kota Miura # miura@embl.de Plugins>EMBLtools, "Bleach Correction", emblcmci.BleachCorrection
Switch between Java6 and Java7 (OSX)
JDK version often becomes problem, since plugin compiled using Java7 cannot be used in ImageJ. Here is one way of switching environments in terminal. Place the following lines in .profile (in case of OSX).
export JAVA_HOME=$(/usr/libexec/java_home -v 1.6* alias setjdk16='export JAVA_HOME=$(/usr/libexec/java_home -v 1.6*)' alias setjdk17='export JAVA_HOME=$(/usr/libexec/java_home -v 1.7*)'
With this, default environment will be Java6, and when you want to switch to java7, then “setjdk7” will switch the environment to Java7.
Listing all Java machines (OSX)
/usr/libexec/java_home -V
This command outputs an example like below.
mac-almf3:~ miura$ /usr/libexec/java_home -V Matching Java Virtual Machines (5): 1.8.0_45, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home 1.8.0_31, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home 1.7.0_17, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_17.jdk/Contents/Home 1.6.0_65-b14-462, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home 1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home
By the way, as of 20150620:
The current ImageJ Launcher only looks for Java SE installations in /Library/Java/JavaVirtualMachines
https://groups.google.com/forum/#!topic/fiji-devel/iftcQAEdPuA
Generating Javadoc
Here is an example code of generating Javadoc of all subpackages of the root package “examplepack” and store them under a directory “doc”.
javadoc -d ./doc -sourcepath ./src/main/java -subpackages examplepack
See more details in the following page. http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javadoc.html
Maven
Executing a test Main class from command line
Example:
mvn exec:java -Dexec.classpathScope=test -Dexec.mainClass="net.imagej.ui.swing.script.ScriptEditorTestDrive"
ImageJ
Running single instance ImageJ (in OSX)
Though there is an option available in windows, there is none in OSX and here is the way to run a ImageJ with socket listener running, that no second ImageJ instance is created. This is convenient for feeding your macro code to the running ImageJ.
java -jar /Applications/ImageJ/ImageJ64.app/Contents/Resources/Java/ij.jar -ijpath /Applications/ImageJ/plugins -eval 'eval("python", "Prefs.runSocketListener=1")'