如何调整pom.xml以访问相同包但不同构建目录中的jar?

时间:2018-06-04 04:00:19

标签: java maven dependencies classloader pom.xml

我有一个带有两个独立组件的Java项目,它们构建为两个独立的.jar文件,其中一个是代理,另一个是运行时。

我试图让代理(Agent.java)在运行时运行main() LangagentApplication.java方法,首先使用ClassLoader.getResource()来访问包含的.jar文件LangagentApplication,但我实际上无法访问运行时.jar文件。我目前正在使用以下内容:getResource("target/runtime.jar"),它只是返回null。打印类路径时,不包括运行时.jar。

请参阅下面的目录结构。

project
--pom.xml
--agent
  --src
    --main/java/.../Agent.java
  --target
    --agent.jar
    --...
  --pom.xml
--runtime
  --src
    --main/java/.../LangagentApplication.java
  --target
    --runtime.jar
    --...
  --pom.xml

注意:
- 为了简单起见,我将jar文件称为agent.jarruntime.jar - 它们的实际名称更长更麻烦。
- 代理程序和运行时都使用相同的程序包(com.spnlangagent.langagent
- Java 1.8

我正在运行Maven和Java,如下所示(来自项目目录):

mvn package
java -cp /path/to/project/runtime/target/runtime.jar -javaagent:/path/to/project/agent/target/agent.jar -jar otherjar.jar

我目前正在执行以下代码:

private static void startRuntime(String agentArgs) throws Exception {
    System.out.println("startRuntime: now running with agentArgs: " + agentArgs);
    //Create a temporary file for the jar
    File output = File.createTempFile("runtime", "jar");
    //Attempt to load the runtime jar
    try (InputStream inputStream = ClassLoader.getSystemClassLoader().getResource("target/runtime.jar").openStream()) {
        Files.copy(inputStream, output.toPath(), StandardCopyOption.REPLACE_EXISTING);
    } catch(NullPointerException npe) {
        System.out.println("Null Pointer Exception when trying to get runtime agent jar. Since it was not found, aborting.");
        npe.printStackTrace();
        System.exit(1);
    }

    //NOTE: This is as far as the code ever gets - remainder of method kept to show intention

    System.out.println("startRuntime: now creating runtime class loader");
    //Handle classloaders.
    ClassLoader extClassLoader = ClassLoader.getSystemClassLoader().getParent();
    URL[] runtimejarurl = {output.toURI().toURL()};
    ClassLoader runtimeClassLoader = new URLClassLoader(runtimejarurl, null);

    System.out.println("startRuntime: now replacing class loader parent field");
    //Replaces the native bootstrap class loader with ours
    Field f = ClassLoader.class.getDeclaredField("parent");
    f.setAccessible(true);
    f.set(extClassLoader, runtimeClassLoader);
    f.setAccessible(false);

    System.out.println("startRuntime: now running Langagent Application main");
    //Have the system class loader load our runtime agent class.
    Class<?> runtimeClass = ClassLoader.getSystemClassLoader().loadClass("com.spnlangagent.langagent.LangagentApplication");
    //Run the main method of the runtime agent
    runtimeClass.getDeclaredMethod("main", String.class).invoke(null, agentArgs);
}

正在捕获Null指针异常,这意味着无法找到资源。我假设这是因为代理假定它在自己的目标目录中查找并且没有考虑(或不能访问)运行时的目标目录。

我正在使用Maven,因此代理有一个src和一个目标目录,运行时有一个src和一个目标目录。我的目标是让代理模块中的Agent类调用位于运行时目标目录中.jar中的LangagentApplication类的main()方法,这要求Maven能够首先构建运行时然后允许代理将运行时添加到其类路径。

我的问题如下: 我应该如何配置我的maven pom.xml文件以允许Agent.java找到.jar,无论是通过构建命令/本地依赖/等,假设运行时的类路径不包含运行时.jar?

谢谢。

0 个答案:

没有答案