Загрузите JAR-файл агента Java, расположенный внутри загрузчика

В моей IDE есть два отдельных проекта для агента и загрузчика, который находит целевую виртуальную машину и загружает JAR агента.

  • Когда проект агента построен, результирующий артефакт JAR агента копируется в папку ресурсов загрузчика.
  • Когда проект загрузчика построен, JAR загрузчика содержит как код загрузчика, так и agent.jar в этом.

Результирующая структура запускаемого загрузчика выглядит так:

       loader.jar
├── META-INF
│   └── MANIFEST.MF
├── me.domain.loader
│   └── Main.class
└── agent.jar
    ├── META-INF
    │   └── MANIFEST.MF
    └── me.domain.agent
        └── Agent.class

Из спецификации VirtualMachine#loadAgent(java.lang.String) мне нужно указать путь к JAR, содержащему агент в качестве первого параметра.

Однако при использовании Main.class.getResource("/agent.jar").getPath() Я получаю AgentLoadException: Agent JAR not found or no Agent-Class attribute. Как правильно это сделать?

2 ответа

Решение

Похоже, что загружаемый JAR-файл агента должен существовать на диске. Я решил эту проблему, скопировав встроенный ресурс JAR во временный файл:

private static String getTemporaryResource(String resourceName) {

    // Read embedded resource from this JAR
    InputStream resourceStream = Main.class.getResourceAsStream(resourceName);
    if (resourceStream == null) {
        throw new Exception("Resource not found in the JAR");
    }

    // Create a temporary file in %TEMP%/resource5513111026806316867.tmp
    File temporaryFile = File.createTempFile("resource", null);
    temporaryFile.deleteOnExit();

    // Copy the resource data into the temporary file
    Files.copy(resourceStream, temporaryFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

    // Return the path to temporary file
    return temporaryFile.getAbsolutePath();
}

Затем я использую этот временный путь для загрузки агента:

String tempAgentPath = getTemporaryResource("/agent.jar");
VirtualMachine targetVM = VirtualMachine.attach("1337");
targetVM.loadAgent(tempAgentPath);

У меня уже была такая проблема в проекте maven. В любом случае вам может понадобиться файл манифеста здесь, в META-INF/MANIFEST.MF:

Manifest-Version: 1.0
Agent-Class: com.package.AgentLoader.agentNameHere
Permissions: all-permissions

У вас есть более подробная информация здесь: https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html или Agent JAR не найден или нет атрибута Agent-Class

Другие вопросы по тегам