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")'