Java找到依赖jar的绝对路径

Java找到依赖jar的绝对路径,java,jar,classpath,executable-jar,Java,Jar,Classpath,Executable Jar,我有一个依赖于另一个Jar项目的Jar文件。两个都是薄罐子,在同一个位置。第一个jar具有清单文件,该文件在其类路径属性中列出第二个jar 在第一个jar中,我使用java中的ProcesBuilder类作为进程启动第二个jar。为此,我需要第二个jar的绝对路径。在第一个jar中,我有类XClient 如果我执行XClient.class.getProtectionDomain().getCodeSource().getLocation().Tori().getPath() 我得到了第一个罐子

我有一个依赖于另一个Jar项目的Jar文件。两个都是薄罐子,在同一个位置。第一个jar具有清单文件,该文件在其类路径属性中列出第二个jar

在第一个jar中,我使用java中的ProcesBuilder类作为进程启动第二个jar。为此,我需要第二个jar的绝对路径。在第一个jar中,我有类XClient 如果我执行
XClient.class.getProtectionDomain().getCodeSource().getLocation().Tori().getPath()
我得到了第一个罐子的绝对路径。然后我可以拆分并添加第二个jar的名称(硬编码)来构建绝对路径

在第二个jar中,我有类XServer 如果我这样做

它抛出了一个例外

我不确定我是否采用了正确的方法,但我的目标非常明确,我希望获得依赖jar的绝对路径


请帮助

我尝试使用相同的方法(但使用了
文件=新文件(this.getClass().getProtectionDomain().getCodeSource().toUri())
而不是
getPath()
),但这可能会以不同的方式失败:

  • 当类位于jar中时,File对象指向jar,而不是jar所在的文件夹-因此,如果(File.isFile())File=File.getParentFile()来获取目录而不是jar文件
  • 当jar文件不是由通常的URLClassLoader加载时(我上次尝试是在1.8中,我只知道因为Jigsaw主类加载器不能再转换为URLClassLoader),这可能会返回一些未指定的结果,如果有的话,因此,实际行为取决于系统设置,这会使在不受您控制的远程系统上使用时难以调试
  • UNC路径(Windows共享)本身很容易出错—在其上添加另一层(java)只会增加许多潜在的陷阱—所有人都必须进行测试和调试—结果往往是您告诉客户端要使用什么以及如何设置,而不是按照java原则设计代码:“编写一次,编译一次,到处运行”(顺便说一句:即使您“挂载”了网络共享,这样您就可以通过本地驱动器号而不是远程网络路径对其进行寻址,这也同样适用——但当您尝试链接两台机器时,其中一台机器是另一台机器的克隆,这甚至会导致问题)
  • 正如前面提到的注释:“它不工作”不是一个有用或有意义的描述-如果您收到错误消息(在本例中,您提到异常stacktrace),请将其与生成它的代码一起发布(如果可以访问)
  • 我是如何解决我的问题的?我只是通过swing JFileChooser向用户请求目录/文件。是的,这不是傻瓜式的,也许不是最好的方法——但它的工作原理是swing仍然附带SE JVM(而不是FX)。 如果您想找到路径,请使用Class.getResource()并让java完成这项工作,就像加密一样:不要自己做

    除此之外:您提到的“用例”不需要您尝试去做什么。您说服务器已经在类路径中-因此它在启动时被加载,您可以访问XServer类。最简单的方法是在另一个线程中运行它,而不是分叉另一个进程。如果您知道哪个类有主线程,那么(server.jar的清单将告诉您)您可以在类路径中访问它,只需执行以下操作:

    Thread serverThread=new Thread(new Runnable()
    {
        public void run()
        {
            String[] args=Arrays.asList("required", "parameters");
            XServer.main(args);
        }
    });
    serverThread.start();
    
    如果不需要任何参数,则只需传递一个空字符串数组。因为main()不应引发异常(至少不应引发选中的异常),所以不需要异常

    在所有这些评论向我抛出之前:是的,我非常清楚此类方法可能存在的问题,如类路径问题(相同packagename中的类名相同,但版本不同),这可能比尝试找出绝对路径并启动fork/sub进程更可行。 另外:启动另一个进程可能需要与其流进行交互(向子进程inputstream提供所需的输入,并读取子进程outputstream和errorstream-否则分叉的进程可能会“挂起”当它等待管道被清除时,这是一件痛苦的事情,但是如果不是你自己的代码,那么调试这种问题,你可以在它上附加一个分析器和调试器来找出为什么所有的东西突然停止工作


    如果你真的想(我不认为有任何要求强迫你“你需要”)与客户端一起启动服务器使用java之外的启动脚本,但使用操作系统级别的东西来启动服务器。

    该异常会告诉您和我们错误的确切原因和位置。编辑您的问题并将该异常的整个堆栈跟踪包括在内,包括所有“原因:”部分,作为代码格式的块。
    Thread serverThread=new Thread(new Runnable()
    {
        public void run()
        {
            String[] args=Arrays.asList("required", "parameters");
            XServer.main(args);
        }
    });
    serverThread.start();