Java 7 compatibility issues

Hi there, I’m trying to integrate nd4j into an application running on a quite old tech stack including java 7. When running a really simple piece of code, I get an error regarding the class version:

java.lang.UnsupportedClassVersionError: org/nd4j/linalg/cpu/nativecpu/CpuBackend : Unsupported major.minor version 52.0

The nd4j getting started guide states that jdk 1.7 is the minimum version, but the error states that the class has been compiled using java 8.
Is this a bug or is the getting started guide not up to date with the minimal requirements of nd4j?

Thanks,
Martin

For the most part it should still be compatible with Java 7. What part is it that throws this error?

It’s a simple UnitTest I’ve write to confirm that nd4j has been loaded correctly by just invoking a method:

import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;

public class Nd4jTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(Nd4jTest.class);

    @Test
    public void testJd4jIsPresent() {
        INDArray x = Nd4j.zeros(3,4);
        assertThat(x, is(notNullValue()));
    }

}

When running on java 8, the test succeeds, but on java 7, I get the error I mentioned in my first post:

java.lang.UnsupportedClassVersionError: org/nd4j/linalg/cpu/nativecpu/CpuBackend : Unsupported major.minor version 52.0

at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:278)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:363)
at java.util.ServiceLoader$1.next(ServiceLoader.java:445)
at org.nd4j.linalg.factory.Nd4jBackend.load(Nd4jBackend.java:162)
at org.nd4j.linalg.factory.Nd4j.initContext(Nd4j.java:5128)
at org.nd4j.linalg.factory.Nd4j.<clinit>(Nd4j.java:226)
at com.example.Nd4jTest.testJd4jIsPresent(Nd4jTest.java:19)

You are right, for some reason the default target has been java 8 ever since the beta4 release. However, that change wasn’t fully intentional.

There are a few modules that intentionally require java 8 and up, but that shouldn’t apply to the core modules.

Thanks for having a look!

Is it possible to move the target language level back to java 7 where possible and integrate this in the next release? Should I create an issue on GitHub for this?

Yes, please open an issue on Github about it. Currently we are debating if it is worth it to reintroduce the java 7 compatibility, as even Red Hat is dropping support for OpenJDK7 in June and even android can handle class files compiled for java 8.