Search code examples
javamatlab

verifying that the compiler produces Java 1.5 code


I have a jar file I produced from compiled class files using an ant file with <javac target="1.5" ... /> and I would like to verify that it actually produces 1.5 code. Is there a way to do this?

My version of MATLAB one one of the computers I'm using, uses a JRE 1.5; so it will not run code unless it is JRE 1.5 compatible. It's worked fine with most JAR files I've produced, but I have one that's acting up, with an odd error:

>> s = javaObject('com.example.test.hdf5.Test1');
??? Error using ==> javaObject
No constructor with appropriate signature exists
in Java class com.example.test.hdf5.Test1

even though here's my class, and it has a regular old no-arg constructor:

package com.example.test.hdf5;

import ncsa.hdf.hdf5lib.H5;
import ncsa.hdf.hdf5lib.HDF5Constants;
import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException;
import ncsa.hdf.object.FileFormat;
import ncsa.hdf.object.h5.H5File;

public class Test1 {
    public Test1 () {}

    public static void main(String args[])
    {
        Test1 test = new Test1();
        if (args.length < 2)
        {

        }
        else if ("h5file".equals(args[0]))
        {
            test.testH5File(args[1]);
        }
        else if ("h5f".equals(args[0]))
        {
            test.testH5F(args[1]);          
        }
    }

    public void testH5File(String filename) {
        H5File file;
        try
        {
            file = (H5File) new H5File().createFile(
                    filename, FileFormat.FILE_CREATE_OPEN);
            file.close();
            System.out.println("Success!");
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    public void testH5F(String filename) {
        try {
            int id = H5.H5Fopen(filename, 
                    HDF5Constants.H5F_ACC_RDONLY, HDF5Constants.H5P_DEFAULT);
            H5.H5Fclose(id);
            System.out.println("Success!");
        }
        catch (HDF5LibraryException e) {
            throw new RuntimeException(e);
        }
        catch (NullPointerException e) {
            throw new RuntimeException(e);
        }
    }
}

Another file produced in the same package + jar file works fine:

package com.example.test.hdf5;

public class Test3 {
    public Test3() {}

    private int x=0;

    public int foo() { return ++this.x; }
}

and I'm wondering if there's something that's screwing up the compiler's 1.5-ness by importing a library that may not be 1.5-compatible.


update: both my Test1 and Test3 classes are 1.5 (major=0, minor=49 as per javap -v). I added a Test2.java which is the exact same as Test1 but with the body of the methods commented out, so it has the same signatures. I get the following with javap -s:

C:\proj\java\test-hdf5\dist>javap -s -classpath test-hdf5.jar com.example.test.hdf5.Test1
Compiled from "Test1.java"
public class com.example.test.hdf5.Test1 extends java.lang.Object{
public com.example.test.hdf5.Test1();
  Signature: ()V
public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
public void testH5File(java.lang.String);
  Signature: (Ljava/lang/String;)V
public void testH5F(java.lang.String);
  Signature: (Ljava/lang/String;)V
}


C:\proj\java\test-hdf5\dist>javap -s -classpath test-hdf5.jar com.example.test.hdf5.Test2
Compiled from "Test2.java"
public class com.example.test.hdf5.Test2 extends java.lang.Object{
public com.example.test.hdf5.Test2();
  Signature: ()V
public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
public void testH5File(java.lang.String);
  Signature: (Ljava/lang/String;)V
public void testH5F(java.lang.String);
  Signature: (Ljava/lang/String;)V
}


C:\proj\java\test-hdf5\dist>javap -s -classpath test-hdf5.jar com.example.test.hdf5.Test3
Compiled from "Test3.java"
public class com.example.test.hdf5.Test3 extends java.lang.Object{
public com.example.test.hdf5.Test3();
  Signature: ()V
public int foo();
  Signature: ()I
}

I guess there's just something really weird going on in the HDF5 library JHDF5.jar that causes MATLAB to reject my Test1 class.

update 2 >:( >:( >:( The JHDF5.jar file has version 50 (JRE1.6), so that's probably what's causing me to lose. Phooey to Matlab for not producing a meaningful error message, and Phooey to HDF5 for compiling with JRE1.6 instead of 1.5 or earlier; I'm very doubtful they're using any of the 1.6 features. I'll file a bug report.


Solution

  • To determine the Java bytecode version of a class file, use javap -v <classname>. This will output something like

    minor version: 0
    major version: 49
    

    Major version 49 is Java platform version 1.5 (48 is 1.4, 50 is 1.6)