java.lang.NoSuchMethodError 使用 Java 9 个模块时 (JPMS)
java.lang.NoSuchMethodError when using Java 9 modules (JPMS)
我正在尝试使用 JPMS 模块组合 JavaFX、Spring Boot 和 VLCJ。没有 Spring 引导,在我的 module-info.java
文件中一切正常:
module myapplication.module {
requires javafx.controls;
requires javafx.fxml;
requires javafx.web;
requires vlcj;
requires org.kordamp.iconli.core;
requires org.kordamp.ikonli.javafx;
requires org.kordamp.ikonli.fontawesome5;
exports com.company.app;
}
但是,如果我现在将 Spring Boot 加入其中,我更新了我的 module-info.java
以包含 Spring 相关模块:
requires spring.beans;
requires spring.context;
requires spring.core;
requires spring.boot.autoconfigure;
requires spring.boot;
但是,我在运行时遇到这个异常:
java.lang.NoSuchMethodError: com.sun.jna.Native.load(Ljava/lang/String;Ljava/lang/Class;)Lcom/sun/jna/Library;
at vlcj.natives@4.1.0/uk.co.caprica.vlcj.binding.LibC.<clinit>(LibC.java:38)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.discovery.strategy.OsxNativeDiscoveryStrategy.setPluginPath(OsxNativeDiscoveryStrategy.java:72)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.discovery.strategy.BaseNativeDiscoveryStrategy.onSetPluginPath(BaseNativeDiscoveryStrategy.java:126)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.discovery.NativeDiscovery.tryPluginPath(NativeDiscovery.java:176)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.discovery.NativeDiscovery.discover(NativeDiscovery.java:117)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.MediaPlayerFactory.discoverNativeLibrary(MediaPlayerFactory.java:187)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.MediaPlayerFactory.<init>(MediaPlayerFactory.java:119)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.MediaPlayerFactory.<init>(MediaPlayerFactory.java:174)
at myapplication.module/com.company.app.MyApplication.mediaPlayerFactory(MyApplicationConfiguration.java:18)
at myapplication.module/com.company.app.MyApplication$$EnhancerBySpringCGLIB$2eae01.CGLIB$mediaPlayerFactory[=14=](<generated>)
at myapplication.module/com.company.app.MyApplication$$EnhancerBySpringCGLIB$2eae01$$FastClassBySpringCGLIB$$af782040.invoke(<generated>)
at spring.core@5.1.9.RELEASE/org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at spring.context@5.1.9.RELEASE/org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
at myapplication.module/com.company.app.MyApplication$$EnhancerBySpringCGLIB$2eae01.mediaPlayerFactory(<generated>)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at spring.beans@5.1.9.RELEASE/org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 34 more
com.sun.jna.Native
是一个 class,它是依赖树的一部分,因为它是 VLCJ 的传递依赖:
[INFO] +- uk.co.caprica:vlcj:jar:4.2.0:compile
[INFO] | \- uk.co.caprica:vlcj-natives:jar:4.1.0:compile
[INFO] | +- net.java.dev.jna:jna:jar:4.5.2:compile
[INFO] | \- net.java.dev.jna:jna-platform:jar:4.5.2:compile
我也尝试在我的模块描述符中添加 requires jna;
,但这并没有改变任何东西。
发布问题 10 分钟后我自己找到了答案:-)
问题不是 Java 模块系统,而是 Spring 引导引入比 VLCJ 需要的版本更旧的 JNA 版本。不知道为什么 Maven 决定这样做或者为什么 Spring Boot 为 JNA 声明一个版本,但是添加依赖项显式修复它:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.4.0</version>
</dependency>
我正在尝试使用 JPMS 模块组合 JavaFX、Spring Boot 和 VLCJ。没有 Spring 引导,在我的 module-info.java
文件中一切正常:
module myapplication.module {
requires javafx.controls;
requires javafx.fxml;
requires javafx.web;
requires vlcj;
requires org.kordamp.iconli.core;
requires org.kordamp.ikonli.javafx;
requires org.kordamp.ikonli.fontawesome5;
exports com.company.app;
}
但是,如果我现在将 Spring Boot 加入其中,我更新了我的 module-info.java
以包含 Spring 相关模块:
requires spring.beans;
requires spring.context;
requires spring.core;
requires spring.boot.autoconfigure;
requires spring.boot;
但是,我在运行时遇到这个异常:
java.lang.NoSuchMethodError: com.sun.jna.Native.load(Ljava/lang/String;Ljava/lang/Class;)Lcom/sun/jna/Library;
at vlcj.natives@4.1.0/uk.co.caprica.vlcj.binding.LibC.<clinit>(LibC.java:38)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.discovery.strategy.OsxNativeDiscoveryStrategy.setPluginPath(OsxNativeDiscoveryStrategy.java:72)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.discovery.strategy.BaseNativeDiscoveryStrategy.onSetPluginPath(BaseNativeDiscoveryStrategy.java:126)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.discovery.NativeDiscovery.tryPluginPath(NativeDiscovery.java:176)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.discovery.NativeDiscovery.discover(NativeDiscovery.java:117)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.MediaPlayerFactory.discoverNativeLibrary(MediaPlayerFactory.java:187)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.MediaPlayerFactory.<init>(MediaPlayerFactory.java:119)
at vlcj@4.2.0/uk.co.caprica.vlcj.factory.MediaPlayerFactory.<init>(MediaPlayerFactory.java:174)
at myapplication.module/com.company.app.MyApplication.mediaPlayerFactory(MyApplicationConfiguration.java:18)
at myapplication.module/com.company.app.MyApplication$$EnhancerBySpringCGLIB$2eae01.CGLIB$mediaPlayerFactory[=14=](<generated>)
at myapplication.module/com.company.app.MyApplication$$EnhancerBySpringCGLIB$2eae01$$FastClassBySpringCGLIB$$af782040.invoke(<generated>)
at spring.core@5.1.9.RELEASE/org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at spring.context@5.1.9.RELEASE/org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
at myapplication.module/com.company.app.MyApplication$$EnhancerBySpringCGLIB$2eae01.mediaPlayerFactory(<generated>)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at spring.beans@5.1.9.RELEASE/org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 34 more
com.sun.jna.Native
是一个 class,它是依赖树的一部分,因为它是 VLCJ 的传递依赖:
[INFO] +- uk.co.caprica:vlcj:jar:4.2.0:compile
[INFO] | \- uk.co.caprica:vlcj-natives:jar:4.1.0:compile
[INFO] | +- net.java.dev.jna:jna:jar:4.5.2:compile
[INFO] | \- net.java.dev.jna:jna-platform:jar:4.5.2:compile
我也尝试在我的模块描述符中添加 requires jna;
,但这并没有改变任何东西。
发布问题 10 分钟后我自己找到了答案:-)
问题不是 Java 模块系统,而是 Spring 引导引入比 VLCJ 需要的版本更旧的 JNA 版本。不知道为什么 Maven 决定这样做或者为什么 Spring Boot 为 JNA 声明一个版本,但是添加依赖项显式修复它:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.4.0</version>
</dependency>