jna 平台中的 NoSuchMethodError

Posted

技术标签:

【中文标题】jna 平台中的 NoSuchMethodError【英文标题】:NoSuchMethodError in jna-platform 【发布时间】:2019-09-22 17:17:29 【问题描述】:

我想发布应用程序的新版本,但启动时会抛出 NoSuchMethodError

java.lang.NoSuchMethodError: com.sun.jna.Native.load(Ljava/lang/String;Ljava/lang/Class;Ljava/util/Map;)Lcom/sun/jna/Library;
    at com.sun.jna.platform.win32.Shell32.<clinit>(Shell32.java:45)
    at com.sun.jna.platform.win32.Shell32Util.getFolderPath(Shell32Util.java:54)
    at com.sun.jna.platform.win32.Shell32Util.getFolderPath(Shell32Util.java:71)
    at com.faforever.client.preferences.PreferencesService.<clinit>(PreferencesService.java:78)
    at com.faforever.client.FafClientApplication.main(FafClientApplication.java:55)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at com.exe4j.runtime.LauncherEngine.launch(LauncherEngine.java:85)
    at com.exe4j.runtime.WinLauncher.main(WinLauncher.java:94)
    at com.install4j.runtime.launcher.WinLauncher.main(WinLauncher.java:25)

类似于 NoSuchMethodError using JNA User32 platform map 但是我确实有两个库的 5.0.0 版本。

关于这个项目https://github.com/FAForever/downlords-faf-client 它使用 gradle 作为构建工具...

我还反编译了安装的程序,发现jna库中不存在java声称的方法。我觉得这很奇怪。

我还检查了没有其他依赖项对 jna 有依赖项。

但最奇怪的是,当我从 intelij (oracle jdk 10) 运行它时它可以工作,但是如果我构建安装程序(travis 上的 openjdk 10)它就不能(同一台机器)。

它以前也有效,我们没有更改与 jna 相关的代码或库版本的任何内容。可能改变的是 travis 使用的 openjdk 版本,但我看不出这有什么关系。

有没有人知道是什么原因造成的......

这是实际失败的代码:

Paths.get(Shell32Util.getFolderPath(ShlObj.CSIDL_COMMON_APPDATA), "FAForever")

虽然我认为这不是问题......

这是jvm日志https://drive.google.com/file/d/11RpxvFubYM7vCoAE-Kx_6EkIKADPQofE/view?usp=sharing

这可能是最重要的部分:

[3.689s][debug][class,resolve               ] com.sun.jna.Native java.lang.Object (super)
[3.689s][debug][class,resolve               ] com.sun.jna.Native com.sun.jna.Version (interface)
[3.689s][debug][class,resolve               ] com.sun.jna.platform.win32.Shell32 com.sun.jna.Native Shell32.java:45 (explicit)
[3.689s][debug][protectiondomain            ] Checking package access
[3.689s][debug][protectiondomain            ] class loader: a 'jdk/internal/loader/ClassLoaders$AppClassLoader'0x00000000ee70de08 protection domain: a 'java/security/ProtectionDomain'0x00000000ef103908 loading: 'com/sun/jna/Native'
[3.689s][debug][protectiondomain            ] granted
[3.689s][trace][protectiondomain            ] pd set count = #1
[3.689s][debug][class,resolve               ] com.sun.jna.platform.win32.Shell32 com.sun.jna.Native Shell32.java:45
[3.689s][info ][stacktrace                  ] java.lang.NoSuchMethodError, 12
[3.689s][info ][exceptions                  ] Exception <a 'java/lang/NoSuchMethodError'0x00000000ef00dd70: com.sun.jna.Native.load(Ljava/lang/String;Ljava/lang/Class;Ljava/util/Map;)Lcom/sun/jna/Library;> (0x00000000ef00dd70) 
thrown [t:/workspace/open/src/hotspot/share/interpreter/linkResolver.cpp, line 741]
for thread 0x00000000031a5000

可能我添加的discord库也包含jna,见jvm的日志:

[3.689s][info ][class,load                  ] com.sun.jna.Native source: file:/E:/DownlordClient%20RC/Downlord's%20FAF%20Client/lib/discord-rpc-1.6.2.jar

【问题讨论】:

我认为在项目 github 页面上打开新问题会更好,因为这看起来像是项目的问题,而不是您编写的代码 如果你问我,jna 库不会有问题,因为正如我所说,当我反编译时,我可以找到似乎缺少的方法 或者你的意思是抛出错误的程序......是的,我是维护者打开一个问题不会有帮助:D 我明白了,你是downlords-faf-client的维护者?我以为你是外部用户。在那种情况下,您可以发布失败的代码吗? 【参考方案1】:

与 JNA 相关的 NoSuchMethodError 几乎总是与在您的依赖项列表中的某个位置有旧版本的 JNA 相关,即使您也有当前版本。

您在此处的评论给出了提示:

可能我添加的discord库也包含jna,见jvm的日志

查看该库的 POM,我们看到:

<name>DiscordRPC</name>
<version>1.6.2</version>
...
<dependencies>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>4.5.1</version>
        <scope>compile</scope>
    </dependency>
    ...
</dependencies>

因此,您很可能处于 Gradle 的依赖解析选择使用较旧的 jna 的情况下,即使您两者都可用,并且您可能拥有 jna-platform 版本 5.0.0 和 jna 版本 4.5.1。

对于jnajna-platform,您应该update your build script to force 使用5.0.0(或更新的)版本。

【讨论】:

我正在尝试正确地遮蔽不和谐库,但它似乎真的很难 idk。 github.com/Vatuu/discord-rpc/pull/35

以上是关于jna 平台中的 NoSuchMethodError的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot常见问题Unable to start embedded container; nested exception is java.lang.NoSuchMethodErro(代码

java高级用法之:JNA中的Memory和Pointer

java高级用法之:JNA中的Structure

java高级用法之:JNA中的回调

Java中jna的用法

JNA 结构和指针映射