有趣的是,我的 war 文件中的 slf4j
依赖项提示
java.lang.UnsupportedClassVersionError: JVMCFRE003 bad major version; class=org/slf4j/impl/StaticLoggerBinder, offset=6
这是 Websphere 8.5 中使用的 Java 版本
Java version = 1.6.0, Java Compiler = j9jit26, Java VM name = IBM J9 VM
并且 slf4j-api-1.7.5.jar
和 slf4j-simple-1.7.5.jar
的 MANIFEST.MF 为
Build-Jdk: 1.6.0_23
我只能想到 IBM JDK 与 Sun JDK 不同,但它们仍然是相同的 java 版本(6),所以为什么还会出现异常?
我认为该错误是由于运行环境是旧的JDK而导致的,但该文件是在新的JDK中编译的。
最佳答案
(另请参阅此答案,它直接涉及 java 类资源的主要版本和次要版本: List of Java class file format major version numbers? 。)
最有可能的是,该类的主要版本高于您的环境所支持的版本。
您需要查看实际的类字节来了解“StaticLoggerBinder”的主要版本是什么,才能确切地知道发生异常的原因。即该条目的字节数:
org/slf4j/impl/StaticLoggerBinder.class
JAR 文件:
slf4j-simple-1.7.5.jar
这些 list 属性可能会提供打包 JAR 时使用的构建步骤的良好信息,但它们不是异常所查看的内容。异常(exception)情况是查看存储在原始类字节中的主要版本值和次要版本值。
使用十六进制编辑器(例如,十六进制模式下的 emacs)查看类文件的前几个字节,将显示如下内容:
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..
使用 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];
我们看到前八个字节必须是“神奇”值0xcafebabe,接下来的四个字节是次要版本(通常是0x00),接下来的四个字节是主要版本。通过 J2SE 9,定义的有效主要版本和次要版本值是:
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"
示例字节显示 0x32 或 J2SE 6.0 的主要版本。
该表取自该实用程序枚举:
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 ...
}
从正在检查的类资源的原始字节值中获取“majorVersion”和“minorVersion”。
关于java.lang.UnsupportedClassVersionError : JVMCFRE003 bad major version; class=org/slf4j/impl/StaticLoggerBinder, 偏移=6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45641900/