java.lang.UnsatisfiedLinkError: URI scheme is not "file" with javafx:jlink

java.lang.UnsatisfiedLinkError: URI scheme is not "file" with javafx:jlink

你好,我正在使用 jnativehook 库和 javafx 运行 mvn javafx:run 工作正常但是 mvn javafx:jlink 无法启动启动器,这里是 javafx 插件 xml,

<plugin>
   <groupId>org.openjfx</groupId>
   <artifactId>javafx-maven-plugin</artifactId>
   <version>0.0.6</version>
   <executions>
      <execution>
         <id>default-cli</id>
         <configuration>
            <launcher>launcher</launcher>
            <mainClass>facsimile/com.github.srilakshmikanthanp.facsimile.Launcher</mainClass>
         </configuration>
      </execution>
   </executions>
</plugin>

这是堆栈跟踪,

java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1071)
Caused by: java.lang.RuntimeException: Exception in Application start method
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication(LauncherImpl.java:195)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.UnsatisfiedLinkError: URI scheme is not "file"
        at com.github.kwhat.jnativehook@2.2-SNAPSHOT/com.github.kwhat.jnativehook.GlobalScreen.<clinit>(GlobalScreen.java:91)        
        at facsimile@1.0.0/com.github.srilakshmikanthanp.facsimile.Launcher.start(Launcher.java:34)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1(LauncherImpl.java:846)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait(PlatformImpl.java:455)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:428)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:427)
        at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(WinApplication.java:174)
        ... 1 more
Exception running application com.github.srilakshmikanthanp.facsimile.Launcher

github 存储库是 here at line,如何解决这个错误?

注意

JavaFX 具有内置的键盘处理功能。

绝对不要这样做除非你需要一些JavaFX没有内置的功能。

就是说。 . .如果你真的需要这样做。 . .

我通过以下步骤使它起作用:

  1. 通过 Idea 创建了一个新的 JavaFX 项目 New JavaFX project wizard

  2. 添加了对 JNativeHook 2.2-SNAPSHOT 的依赖。

    • 需要快照,因为 2.2.1 版本模块信息对我不起作用。

      <dependency>
          <groupId>com.github.kwhat</groupId>
          <artifactId>jnativehook</artifactId>
          <version>2.2-SNAPSHOT</version>
      </dependency>
      
    • 需要启用 sonatype 快照存储库才能访问它。

      <repositories>
         <repository>
            <id>oss.sonatype.org-snapshot</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
         </repository>
      </repositories>
      
  3. 向应用程序添加了导入:

    import com.github.kwhat.jnativehook.GlobalScreen;
    
  4. 在应用程序的启动方法中添加了以下行:

    GlobalScreen.registerNativeHook();
    
  5. 在应用程序的停止方法中添加了以下行:

    GlobalScreen.unregisterNativeHook();
    
  6. 将以下行添加到模块-info.java

    requires com.github.kwhat.jnativehook;
    
  7. 链接应用程序:

    • 在maven window 中右击Plugins | javafx | javafx:jlink 并选择“运行 Maven 构建”。
  8. 从 jar 中提取本机库。

    • 右键单击 jnativehook-<longversioninfo>.jar

    • 选择复制Path/Reference... |绝对路径

    • 在命令行中 window jar xvf <copied path>

    • 为平台找到合适的本机库。

      find . | grep dylib   
      
    • 对我来说它是一个英特尔 mac,所以文件是:

      ./com/github/kwhat/jnativehook/lib/darwin/x86_64/libJNativeHook.dylib
      
    • 名称已通过添加到启动方法的此行的输出确认:

      System.out.println("libname: " + System.mapLibraryName("JNativeHook"));           
      
  9. 将原生库libJNativeHook.dylib复制到为jlink创建的应用程序创建的lib目录,这是:

    <projectname>/target/app/lib
    
  10. 尝试 运行 应用:

    cd <projectname>/target/app/bin
    ./app
    
  11. App 运行 将失败并出现以下错误(意味着本机库已加载并且存在另一个错误):

    Caused by: com.github.kwhat.jnativehook.NativeHookException: Failed to enable access for assistive devices.
    
  12. 按照此处的说明为终端应用程序启用辅助设备:

  13. 运行 再次应用:

    ./app
    

现在应用 运行 没问题了。 . .

也许有更简单的方法来做到这一点。 . .我不知道。

如果需要,您可以 create an issue 要求 jnativehook 开发人员简化此操作。如果你这样做,肯定 link 回到这个问题的上下文。

当 jlink 完成时,可以通过某种方式(我不知道如何)获取 JavaFX 库,而无需将本机库复制到 jlink 输出库目录手动。也许为 JavaFX 所做的一切都可以为 jnativehook 完成,以使其更易于与 jlink/jpackage.

一起使用