Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何调整pom.xml以访问同一个包中但不同构建目录中的jar?_Java_Maven_Dependencies_Classloader_Pom.xml - Fatal编程技术网

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

Java 如何调整pom.xml以访问同一个包中但不同构建目录中的jar?,java,maven,dependencies,classloader,pom.xml,Java,Maven,Dependencies,Classloader,Pom.xml,我有一个Java项目,它有两个独立的组件,构建成两个独立的.jar文件,其中一个是代理,另一个是运行时 我试图让代理(agent.java)在运行时运行LangagentApplication.java的main()方法,首先使用ClassLoader.getResource()访问包含LangagentApplication的.jar文件,但我在实际访问runtime.jar文件时遇到问题。我目前正在使用以下命令:getResource(“target/runtime.jar”),它只是返回n

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

我试图让代理(
agent.java
)在运行时运行
LangagentApplication.java
main()
方法,首先使用
ClassLoader.getResource()
访问包含LangagentApplication的.jar文件,但我在实际访问runtime.jar文件时遇到问题。我目前正在使用以下命令:
getResource(“target/runtime.jar”)
,它只是返回
null
。打印类路径时,不包括runtime.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.jar
runtime.jar
,它们的实际名称更长更混乱。
-代理和运行时都使用相同的包(
com.spnlangagent.langagent

-Java 1.8

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

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

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);
}
private static void startRuntime(字符串agentArgs)引发异常{
System.out.println(“startRuntime:现在与agentArgs一起运行:“+agentArgs”);
//为jar创建一个临时文件
文件输出=File.createTempFile(“运行时”、“jar”);
//尝试加载运行时jar
try(InputStream InputStream=ClassLoader.getSystemClassLoader().getResource(“target/runtime.jar”).openStream()){
copy(inputStream,output.toPath(),StandardCopyOption.REPLACE_EXISTING);
}捕获(NullPointerException npe){
System.out.println(“尝试获取运行时代理jar时出现空指针异常,因为找不到,正在中止”);
npe.printStackTrace();
系统出口(1);
}
//注意:这是代码所能得到的——保留方法的剩余部分以显示意图
System.out.println(“startRuntime:now creating runtime class loader”);
//处理类装入器。
ClassLoader extClassLoader=ClassLoader.getSystemClassLoader().getParent();
URL[]runtimejarurl={output.toURI().toURL()};
ClassLoader runtimeClassLoader=新的URLClassLoader(runtimejarurl,null);
System.out.println(“startRuntime:现在替换类加载器父字段”);
//将本机引导类装入器替换为我们的
字段f=ClassLoader.class.getDeclaredField(“父项”);
f、 setAccessible(true);
f、 set(extClassLoader、runtimeClassLoader);
f、 setAccessible(false);
System.out.println(“startRuntime:now running Langagent Application main”);
//让系统类加载器加载我们的运行时代理类。
类runtimeClass=ClassLoader.getSystemClassLoader().loadClass(“com.spnlangagent.langagent.LangagentApplication”);
//运行运行时代理的main方法
runtimeClass.getDeclaredMethod(“main”,String.class).invoke(null,agentArgs);
}
正在捕获空指针异常,这意味着找不到资源。我假定这是因为代理假定它正在查看自己的目标目录,并且没有考虑(或无法访问)运行时的目标目录

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

我的问题如下: 考虑到运行时的类路径不包括runtime.jar,我应该如何配置maven pom.xml文件以允许
Agent.java
定位.jar,无论是通过构建命令/本地依赖项/etc


谢谢。

您无法将target/runtime.jar作为类资源。这个jar已经添加到类路径中,因此jar的内容是可用的,而不是jar本身。如果您希望将jar作为一个可读的(出于某种原因)资源,那么target/runtime.jar必须捆绑在agent.jar中。我想你不想那样。这两个jar在类路径中都可用吗?如果是,为什么不直接调用LangagentApplication而不进行反思呢。如果没有,则使用UrlClassloader而不进行任何复制。阐明您的意图。我想做的是从代理jar中的一个方法执行LangagentApplication的主方法(在运行时jar中)。您没有解释的是这两个jar是否在类路径中?在执行代理类时,您是如何放置这两个jar的。我正在按如下方式运行代理:
java-javaagent:/Users/andrewfan/Desktop/Spn LangAgent/agent/target/Spn-LangAgent-agent-0.0.jar-jar
我目前没有直接为代理或运行时设置-cp。jar文件相对于项目目录的位置与我的问题中描述的完全相同。@gagansingh我做了一些测试,没有,运行时jar根本不在类路径中-只有运行代理的代理和目标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);
}