【问题标题】:How to put classes for javaagent in the classpath如何将 javaagent 的类放在类路径中
【发布时间】:2013-03-30 03:41:22
【问题描述】:

我正在尝试开发一个 javaagent,它可以在 asm-4 的帮助下检测代码。现在我遇到了一个非常基本的问题,javaagent 的类加载器没有看到 asm 依赖项,因此失败了。我是否必须提供一个 jar-with-dependencies(又名 maven 构建插件),其中包含代理所需的所有类,还是有另一种方法可以将类添加到 java 代理? 直接在类路径中引用 jar asm-all.jar 没有帮助。 最初构建 jar-with-dependencies 并没有帮助,因为 Premain-Class 属性无法使用程序集插件设置。 感谢您的帮助;-)

【问题讨论】:

  • 好的,显然我自己找到了答案:test.agent.MyAgent
  • 请将其写为答案并接受,以便其他用户看到您的问题的答案。

标签: java maven classpath javaagents


【解决方案1】:

好的,通过实验找到它。 依赖的类应该是jar的一部分,可以通过maven组装插件创建,例如:

    <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>

使用 jar 作为 javaagent 路径,一切正常。

【讨论】:

  • test.agent.MyAgent 很重要 ;-)
【解决方案2】:

我关注了这个blog post。 这是我如何使它工作的,以获取对象的大小。

/MANIFEST.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

在您的 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>

我的仪器代理:

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);
    }
}

我的主应用:

包 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)));

    }

}

将所有内容放在一起和 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

【讨论】:

  • 如果代理和项目在 2 个单独的 jar 中怎么办?
【解决方案3】:

我为我的 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>

【讨论】:

    【解决方案4】:

    我认为您可以在 MyAgent.jar 的 Manifest.mf 文件中指定 Class-Path。

    【讨论】:

      【解决方案5】:

      您应该将 Premain-Class 条目添加到清单中。我使用 gradle 来构建 Java 项目。

      将此添加到gradle.build

      jar {
          manifest {
              attributes(
                      "Premain-Class": "com.training.agent.agentapp.SimplestAgent",
                      "Can-Redefine-Classes": false,
                      "Can-Set-Native-Method-Prefix": false
              )
          }
      }
      

      然后你就可以运行它了

      java -javaagent:agent.jar -jar application.jar
      

      Mode details

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-26
        • 2014-12-18
        • 2011-01-30
        • 2012-07-03
        • 1970-01-01
        • 1970-01-01
        • 2013-11-01
        • 1970-01-01
        相关资源
        最近更新 更多