java 如何将 javaagent 的类放在类路径中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15872642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to put classes for javaagent in the classpath
提问by Leon
I am trying to develop a javaagent that would instrument code with help of asm-4. For now I'm stucked with a pretty basic problem, the classloader for the javaagent doesn't see asm dependencies and therefor fails. Do I have to provide a jar-with-dependencies (aka maven build plugin) which contains all the needed classes by the agent, or is there another way to add classes to the java agent? Referencing the jar asm-all.jar directly in the classpath didn't help. Building jar-with-dependencies didn't help at first, because Premain-Class attribute couldn't be set with assembly plugin. Help is appreciated ;-)
我正在尝试开发一个 javaagent,它可以在 asm-4 的帮助下检测代码。现在我遇到了一个非常基本的问题,javaagent 的类加载器没有看到 asm 依赖项,因此失败。我是否必须提供包含代理所需的所有类的 jar-with-dependencies(又名 maven 构建插件),或者是否有另一种方法将类添加到 java 代理?直接在类路径中引用 jar asm-all.jar 没有帮助。构建 jar-with-dependencies 一开始并没有帮助,因为 Premain-Class 属性不能用程序集插件设置。帮助表示赞赏;-)
采纳答案by Leon
ok, found it by experimenting. The dependent classes should be part of the jar, which can be created by maven assembly plugin, for example:
好的,通过实验找到了它。依赖类应该是jar的一部分,可以通过maven assembly插件创建,例如:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<index>true</index>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Premain-Class>test.agent.MyAgent</Premain-Class>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- this is used for inheritance merges -->
<phase>package</phase>
<!-- append to the packaging phase. -->
<goals>
<goal>single</goal>
<!-- goals == mojos -->
</goals>
</execution>
</executions>
</plugin>
Use the jar as javaagent path and everything works fine.
使用 jar 作为 javaagent 路径,一切正常。
回答by juanmf
I followed this blog post. Here is how I made it work, to get the size of objects.
我关注了这篇博文。这是我如何使它工作,以获取对象的大小。
/MANIFEST.MF
/清单.MF
Manifest-Version: 1.0
Premain-Class: ar.com.docdigital.InstrumentationApp
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Can-Set-Native-Method-Prefix: true
in your pom.xml (Note we reference custom MANIFEST)
在你的 pom.xml (注意我们引用自定义清单)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>
MANIFEST.MF
</manifestFile>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>
ar.com.docdigital.App
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
My Instrumentation Agent:
我的仪器代理:
package ar.com.docdigital;
import java.lang.instrument.Instrumentation;
/**
*
* @author juan.fernandez
*/
public class InstrumentationApp {
private static Instrumentation instrumentation;
public static void premain(String args, Instrumentation inst) {
instrumentation = inst;
}
public static long getObjectSize(Object o) {
return instrumentation.getObjectSize(o);
}
}
My main App:
我的主要应用程序:
package ar.com.docdigital;
包 ar.com.docdigital;
import static ar.com.docdigital.InstrumentationApp.getObjectSize;
/**
*
* @author juan.fernandez
*/
public class App {
public static void main (String[] args) {
System.out.println("Size of CoprimeLong: " + getObjectSize(new CoprimesList.CoprimeLong(1L)));
System.out.println("Size of Long: " + getObjectSize(new Long(1L)));
}
}
Putting all together & CLI output:
将所有内容放在一起和 CLI 输出:
$ mvn package
$ java -javaagent:target/primos-0.1.0-SNAPSHOT.jar -jar target/primos-0.1.0-SNAPSHOT.jar
Size of CoprimeLong: 24
Size of Long: 24
回答by Hymany
I think you can specify Class-Path in the Manifest.mf file in the MyAgent.jar.
我认为您可以在 MyAgent.jar 的 Manifest.mf 文件中指定 Class-Path。
回答by Yan Khonski
You should add Premain-Class entry to the manifest. I use gradle to build Java projects.
您应该将 Premain-Class 条目添加到清单中。我使用 gradle 来构建 Java 项目。
Add this to gradle.build
将此添加到 gradle.build
jar {
manifest {
attributes(
"Premain-Class": "com.training.agent.agentapp.SimplestAgent",
"Can-Redefine-Classes": false,
"Can-Set-Native-Method-Prefix": false
)
}
}
And then you can run it
然后你可以运行它
java -javaagent:agent.jar -jar application.jar
回答by Ashraff Ali Wahab
I used maven-jar-plugin for my CustomAgent. I dont have any dependent modules/jars so using an assembly plugin is an overkill.
我为我的 CustomAgent 使用了 maven-jar-plugin。我没有任何依赖模块/jar,所以使用程序集插件是一种矫枉过正。
<build>
<sourceDirectory>src</sourceDirectory>
<finalName>are-agent</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Premain-Class>are.agent.CustomAgent</Premain-Class>
<Can-Redefine-Classes>false</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
<build>