0

Interestingly, the slf4j dependency from my war file complain about

java.lang.UnsupportedClassVersionError: JVMCFRE003 bad major version; class=org/slf4j/impl/StaticLoggerBinder, offset=6

and this is the Java version used in Websphere 8.5

Java version = 1.6.0, Java Compiler = j9jit26, Java VM name = IBM J9 VM

and the MANIFEST.MF for the slf4j-api-1.7.5.jar and slf4j-simple-1.7.5.jar is

Build-Jdk: 1.6.0_23

I can only think of IBM JDK is different to Sun JDK but still they are in the same java version (6) so how could the exception still occur?

I thought the error is due to the running environment is on old JDK but the file is complied in new JDK.

Dreamer
  • 7,333
  • 24
  • 99
  • 179

4 Answers4

1

(See also this answer, which directly speaks to the major and minor version of java class resources: List of Java class file format major version numbers?.)

Most probably, the major version of the class is higher than is supported in your environment.

You'll need to look at the actual class bytes to tell what the major version is of "StaticLoggerBinder" to know exactly why the exception is occurring. That is, the bytes of this entry:

org/slf4j/impl/StaticLoggerBinder.class

Of the JAR file:

slf4j-simple-1.7.5.jar

Those manifest properties may provide good information from the build steps which were used when JAR was packaged, but they aren't what the exception is looking at. The exception is looking at the major and minor version values which are stored in the raw class bytes.

Looking at the first few bytes of a class file with a hex editor (e.g., emacs in hexl-mode), will show something like this:

00000000: cafe babe 0000 0032 0071 0a00 0f00 4809  .......2.q....H.
00000010: 001f 0049 0900 4a00 4b0a 004c 004d 0800  ...I..J.K..L.M..

Using the class format documentation from Oracle:

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];

We see that the first eight bytes must be the "magic" value 0xcafebabe, the next four bytes are the minor version (which is usually 0x00), and the next four bytes are the major version. Through J2SE 9, the defined valid major and minor version values are:

    JDK_11(45, 3, "JDK 1.1"), // "0x2D"
    JDK_12(46, 0, "JDK 1.2"), // "0x2E"
    JDK_13(47, 0, "JDK 1.3"), // "0x2F"
    JDK_14(48, 0, "JDK 1.4"), // "0x30"
    JDK_50(49, 0, "J2SE 5.0"),// "0x31"
    JDK_60(50, 0, "J2SE 6.0"),// "0x32"
    JDK_7 (51, 0, "J2SE 7"),  // "0x33"
    JDK_8 (52, 0, "J2SE 8"),  // "0x34"
    JDK_9 (53, 0, "J2SE 9");  // "0x35"

The sample bytes show a major version of 0x32, or J2SE 6.0.

That table is taken from this utility enum:

public enum JDKVersion {
    JDK_11(45, 3, "JDK 1.1"), // "0x2D"
    JDK_12(46, 0, "JDK 1.2"), // "0x2E"
    JDK_13(47, 0, "JDK 1.3"), // "0x2F"
    JDK_14(48, 0, "JDK 1.4"), // "0x30"
    JDK_50(49, 0, "J2SE 5.0"),// "0x31"
    JDK_60(50, 0, "J2SE 6.0"),// "0x32"
    JDK_7 (51, 0, "J2SE 7"),  // "0x33"
    JDK_8 (52, 0, "J2SE 8"),  // "0x34"
    JDK_9 (53, 0, "J2SE 9");  // "0x35"

    private JDKVersion(int majorVersion, int minorVersion, String textValue) {
        this.majorVersion = majorVersion;
        this.minorVersion = minorVersion;
        this.textValue = textValue;
    }

    private final int majorVersion;
    private final int minorVersion;
    private final String textValue;

    // getters omitted ...
}

With the "majorVersion" and "minorVersion" obtained from the raw byte values of the class resource which is being examined.

Thomas Bitonti
  • 1,179
  • 7
  • 14
0

Looking at this link, I don't think you're looking at the right jar.

slf4j-api-1.7.5.jar only contains the api, and not the implementation. You'll need to find which jar contains the implementation of StaticLoggerBinder, and that's the jar which has been compiled at a higher version.

mswatosh
  • 466
  • 2
  • 8
  • sorry my bad, my war file also contains `slf4j-simple-1.7.5.jar`. I have updated my question accordingly – Dreamer Aug 11 '17 at 19:09
0
  1. slf4j-api-1.7.5.jar does not contain the StaticLoggerBinder class. Look for the right jar.
  2. You should see the X-Compile-Target-JDK property on the MANIFEST, not the Build-jdk.
leoconco
  • 253
  • 3
  • 15
  • sorry my bad, my war file also contains `slf4j-simple-1.7.5.jar`. I have updated my question accordingly – Dreamer Aug 11 '17 at 19:10
  • 1
    You might have another StaticLoggerBinder in other jar, this class is what slf4j uses to autowire a slf4j implementation. For example, logback has and implementation of this. – leoconco Aug 11 '17 at 19:15
0

If you are using WAS v8.5.5, You need to install JDK 1.7 or 1.8 (if v8.5.5 is updqated to some fixpack) along with WAS v8.5.5 and configure your server to use it

titou10
  • 2,814
  • 1
  • 19
  • 42