java.lang.UnsupportedClassVersionError: JVMCFRE003 bad major version; class=org/slf4j/impl/StaticLoggerBinder, offset=6
java.lang.UnsupportedClassVersionError: JVMCFRE003 bad major version; class=org/slf4j/impl/StaticLoggerBinder, offset=6
有趣的是,我的 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
的 MANIFEST.MF 和 slf4j-simple-1.7.5.jar
是
Build-Jdk: 1.6.0_23
我只能想到 IBM JDK 与 Sun JDK 不同,但它们仍然在相同的 java 版本 (6) 中,怎么还会出现异常?
我认为错误是由于 运行 环境在旧 JDK 上,但文件在新 JDK 中编译。
查看 this link,我认为您没有找到合适的 jar。
slf4j-api-1.7.5.jar 仅包含 api,不包含实现。您需要找到哪个jar 包含StaticLoggerBinder 的实现,并且是在更高版本上编译的jar。
slf4j-api-1.7.5.jar
不包含StaticLoggerBinder
class。
寻找合适的罐子。
- 您应该在 MANIFEST 上看到
X-Compile-Target-JDK
属性,而不是 Build-jdk
。
(另请参阅此答案,它直接说明 java class 资源的主要版本和次要版本:List of Java class file format major version numbers?。)
很可能,class 的主要版本高于您的环境所支持的版本。
您需要查看实际的 class 字节来判断 "StaticLoggerBinder" 的主要版本是什么,以便准确了解异常发生的原因。即这个条目的字节数:
org/slf4j/impl/StaticLoggerBinder.class
JAR 文件的:
slf4j-simple-1.7.5.jar
这些清单属性可能会提供来自构建步骤的有用信息,这些信息是在打包 JAR 时使用的,但它们不是异常所关注的内容。例外情况是查看存储在原始 class 字节中的主要和次要版本值。
使用十六进制编辑器(例如,十六进制模式下的 emacs)查看 class 文件的前几个字节,将显示如下内容:
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 的 class 格式文档:
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];
我们看到前八个字节必须是 "magic" 值 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 的主要版本。
table 取自此实用程序枚举:
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" 从正在检查的 class 资源的原始字节值中获得。
如果您使用的是 WAS v8.5.5,您需要安装 JDK 1.7 或 1.8(如果 v8.5.5 已更新为某些修复包)以及 WAS v8.5.5 并配置您的服务器以使用它
有趣的是,我的 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
的 MANIFEST.MF 和 slf4j-simple-1.7.5.jar
是
Build-Jdk: 1.6.0_23
我只能想到 IBM JDK 与 Sun JDK 不同,但它们仍然在相同的 java 版本 (6) 中,怎么还会出现异常?
我认为错误是由于 运行 环境在旧 JDK 上,但文件在新 JDK 中编译。
查看 this link,我认为您没有找到合适的 jar。
slf4j-api-1.7.5.jar 仅包含 api,不包含实现。您需要找到哪个jar 包含StaticLoggerBinder 的实现,并且是在更高版本上编译的jar。
slf4j-api-1.7.5.jar
不包含StaticLoggerBinder
class。 寻找合适的罐子。- 您应该在 MANIFEST 上看到
X-Compile-Target-JDK
属性,而不是Build-jdk
。
(另请参阅此答案,它直接说明 java class 资源的主要版本和次要版本:List of Java class file format major version numbers?。)
很可能,class 的主要版本高于您的环境所支持的版本。
您需要查看实际的 class 字节来判断 "StaticLoggerBinder" 的主要版本是什么,以便准确了解异常发生的原因。即这个条目的字节数:
org/slf4j/impl/StaticLoggerBinder.class
JAR 文件的:
slf4j-simple-1.7.5.jar
这些清单属性可能会提供来自构建步骤的有用信息,这些信息是在打包 JAR 时使用的,但它们不是异常所关注的内容。例外情况是查看存储在原始 class 字节中的主要和次要版本值。
使用十六进制编辑器(例如,十六进制模式下的 emacs)查看 class 文件的前几个字节,将显示如下内容:
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 的 class 格式文档:
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];
我们看到前八个字节必须是 "magic" 值 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 的主要版本。
table 取自此实用程序枚举:
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" 从正在检查的 class 资源的原始字节值中获得。
如果您使用的是 WAS v8.5.5,您需要安装 JDK 1.7 或 1.8(如果 v8.5.5 已更新为某些修复包)以及 WAS v8.5.5 并配置您的服务器以使用它