Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.NoSuchMethodError when using Java 9 modules (JPMS)

I am trying to combine JavaFX, Spring Boot and VLCJ using JPMS modules. Without Spring Boot, things work fine with this in my module-info.java file:

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;
}

However, if I now bring Spring Boot in the mix, I updated my module-info.java to include the Spring related modules:

    requires spring.beans;
    requires spring.context;
    requires spring.core;
    requires spring.boot.autoconfigure;
    requires spring.boot;

However, I get this exception at runtime:

java.lang.NoSuchMethodError: com.sun.jna.Native.load(Ljava/lang/String;Ljava/lang/Class;)Lcom/sun/jna/Library;
    at [email protected]/uk.co.caprica.vlcj.binding.LibC.<clinit>(LibC.java:38)
    at [email protected]/uk.co.caprica.vlcj.factory.discovery.strategy.OsxNativeDiscoveryStrategy.setPluginPath(OsxNativeDiscoveryStrategy.java:72)
    at [email protected]/uk.co.caprica.vlcj.factory.discovery.strategy.BaseNativeDiscoveryStrategy.onSetPluginPath(BaseNativeDiscoveryStrategy.java:126)
    at [email protected]/uk.co.caprica.vlcj.factory.discovery.NativeDiscovery.tryPluginPath(NativeDiscovery.java:176)
    at [email protected]/uk.co.caprica.vlcj.factory.discovery.NativeDiscovery.discover(NativeDiscovery.java:117)
    at [email protected]/uk.co.caprica.vlcj.factory.MediaPlayerFactory.discoverNativeLibrary(MediaPlayerFactory.java:187)
    at [email protected]/uk.co.caprica.vlcj.factory.MediaPlayerFactory.<init>(MediaPlayerFactory.java:119)
    at [email protected]/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$$702eae01.CGLIB$mediaPlayerFactory$0(<generated>)
    at myapplication.module/com.company.app.MyApplication$$EnhancerBySpringCGLIB$$702eae01$$FastClassBySpringCGLIB$$af782040.invoke(<generated>)
    at [email protected]/org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
    at [email protected]/org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
    at myapplication.module/com.company.app.MyApplication$$EnhancerBySpringCGLIB$$702eae01.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 [email protected]/org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 34 more

com.sun.jna.Native is a class that is part of the dependency tree as it is a transitive dependency of 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

I also tried adding requires jna; in my module descriptor, but that does not change anything.

like image 865
Wim Deblauwe Avatar asked Sep 06 '19 14:09

Wim Deblauwe


People also ask

What causes Java Lang NoSuchMethodError?

lang. NoSuchMethodError is a runtime error in Java which occurs when a method is called that exists at compile-time, but does not exist at runtime. The Java Garbage Collector (GC) cannot free up the space required for a new object, which causes a java. lang.


1 Answers

Found the answer myself 10 minutes after posting the question :-)

The problem is not the Java module system, but Spring Boot pulling in a version of JNA that is older compared to the one that VLCJ needs. Not sure why Maven decided on that or why Spring Boot declares a version for JNA, but adding the dependency explicitly fixes it:

        <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>
like image 195
Wim Deblauwe Avatar answered Oct 22 '22 14:10

Wim Deblauwe