首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >javaagent jar在bootclasspath中的位置

javaagent jar在bootclasspath中的位置
EN

Stack Overflow用户
提问于 2011-04-20 15:29:16
回答 2查看 3.8K关注 0票数 3

我有一个javaagent jar,我将它放在bootclasspath上,使用

代码语言:javascript
复制
Boot-Class-Path: myagent.jar

在MANIFEST.MF文件中。

我需要找出jar所在的文件系统上的目录。

然而,为这个here描述的方法似乎对我不起作用:

代码语言:javascript
复制
 new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().g­etPath());

在这种情况下,ProtectionDomain.getCodeSource()返回null。我猜这是因为jar被放在了引导类路径上。因此,我也不能执行MyClass.getClassLoader()来获取资源位置。

我使用的是Java 6。

有谁能告诉我怎么找到罐子的位置吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-23 14:14:26

您可以使用系统类加载器查找引导类路径上的类。例如,如下所示

代码语言:javascript
复制
System.out.println(
  ClassLoader.getSystemClassLoader().getResource("java/lang/String.class")
);

会打印出这样的东西,

代码语言:javascript
复制
jar:file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/rt.jar!/java/lang/String.class

要查找MyClass.class在磁盘上的位置,请执行以下操作

代码语言:javascript
复制
String urlString = ClassLoader
 .getSystemClassLoader()
 .getResource("com/my/package/MyClass.class")
 .toString();

urlString = urlString.substring(urlString.indexOf("file:"), urlString.indexOf('!'));
URL url = new URL(urlString);
File file = new File(url.toURI());
System.out.println(file);
System.out.println(file.exists());

JavaUpdate2020-06-29 by kriegaex:我不想对这个老问题写一个新的答案,而是想增强或更新这个非常好的答案,并考虑到带有空格和 9+模块的路径。

下面是一个将类文件路径作为File实例返回的方法。如果一个类文件是JAR或Java运行时模块的一部分(URL以协议jrt:开头),它只返回JAR或JMOD文件的路径,这可能不是您想要的,但它只是一个展示,您可以根据自己的内容进行编辑。当然,这仍然是老生常谈,例如,不考虑从web URL加载的类,而不是从文件加载的类,但你明白了。

代码语言:javascript
复制
public static File getFileForClass(String className) {
  className = className.replace('.', '/') + ".class";
  URL classURL = ClassLoader.getSystemClassLoader().getResource(className);
  if (classURL == null)
    return null;
  System.out.println("Class file URL: " + classURL);

  // Adapt this if you also have '.war' or other archive types
  if (classURL.toString().contains(".jar!")) {
    String jarFileName = classURL.getPath().replaceFirst("!.*", "");
    System.out.println("Containing JAR file: " + jarFileName);
    try {
      return new File(new URL(jarFileName).toURI());
    }
    catch (URISyntaxException | MalformedURLException e) {
      throw new RuntimeException(e);
    }
  }

  if (classURL.getProtocol().equals("jrt")) {
    String jrtModule = classURL.getFile().replaceFirst("/([^/]+).*", "$1");
    System.out.println("Target class is part of Java runtime module " + jrtModule);
    String jmodName = System.getProperty("java.home") + "/jmods/" + jrtModule + ".jmod";
    System.out.println("Containing Java module file: " + jmodName);
    return new File(jmodName);
  }
  try {
    return new File(classURL.toURI());
  }
  catch (URISyntaxException e) {
    throw new RuntimeException(e);
  }
}

当我从我的一个IntelliJ IDEA项目中调用它时,JDK14安装在一个包含空格的路径下,并故意添加一个JAR,该JAR也包含一个带有空格的路径用于测试,这段代码...

代码语言:javascript
复制
public static void main(String[] args) throws IOException {
  Instrumentation instrumentation = ByteBuddyAgent.install();
  instrumentation.appendToSystemClassLoaderSearch(
    new JarFile("C:/Program Files/JetBrains/IntelliJ IDEA 2018.3/lib/idea_rt.jar")
  );
  Stream
    .of(
      Weaver.class.getName(),
      String.class.getName(),
      ByteBuddy.class.getName(),
      "com.intellij.execution.TestDiscoveryListener"
    )
    .forEach(className -> System.out.printf("Found file: %s%n%n", getFileForClass(className)));
}

..。产生以下控制台输出:

代码语言:javascript
复制
Class file URL: file:/C:/Users/alexa/Documents/java-src/Sarek/sarek-aspect/target/classes/dev/sarek/agent/aspect/Weaver.class
Found file: C:\Users\alexa\Documents\java-src\Sarek\sarek-aspect\target\classes\dev\sarek\agent\aspect\Weaver.class

Class file URL: jrt:/java.base/java/lang/String.class
Target class is part of Java runtime module java.base
Containing Java module file: C:\Program Files\Java\jdk-14.0.1/jmods/java.base.jmod
Found file: C:\Program Files\Java\jdk-14.0.1\jmods\java.base.jmod

Class file URL: jar:file:/C:/Users/alexa/.m2/repository/net/bytebuddy/byte-buddy/1.10.13/byte-buddy-1.10.13.jar!/net/bytebuddy/ByteBuddy.class
Containing JAR file: file:/C:/Users/alexa/.m2/repository/net/bytebuddy/byte-buddy/1.10.13/byte-buddy-1.10.13.jar
Found file: C:\Users\alexa\.m2\repository\net\bytebuddy\byte-buddy\1.10.13\byte-buddy-1.10.13.jar

Class file URL: jar:file:/C:/Program%20Files/JetBrains/IntelliJ%20IDEA%202018.3/lib/idea_rt.jar!/com/intellij/execution/TestDiscoveryListener.class
Containing JAR file: file:/C:/Program%20Files/JetBrains/IntelliJ%20IDEA%202018.3/lib/idea_rt.jar
Found file: C:\Program Files\JetBrains\IntelliJ IDEA 2018.3\lib\idea_rt.jar
票数 9
EN

Stack Overflow用户

发布于 2011-04-23 12:34:45

你可以这样做:

代码语言:javascript
复制
final String   bootClassPath;
final String[] entries;

// different VM may use a different string here...
bootClassPath = System.getProperty("sun.boot.class.path");
entries       = bootClassPath.split(File.pathSeparator);

for(final String entry : entries)
{
    System.out.println(entry);
}

它遍历引导类路径中的每个条目。对于每个条目,您可以获取JAR文件并查看清单文件,看看它是否是您的。您可以在清单中添加另一个条目来查找,如果还没有唯一要查找的内容。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5726930

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档