Laden Sie eine Java Agent JAR im Loader

Nov 15 2020

Ich habe zwei separate Projekte in meiner IDE für den Agenten und für den Loader, der eine Ziel-VM findet und die Agenten-JAR lädt.

  • Wenn das Agentenprojekt erstellt wird, wird das resultierende JAR-Artefakt des Agenten in den Ressourcenordner des Loaders kopiert.
  • Wenn das Loader-Projekt erstellt wird, enthält die Loader-JAR sowohl den Loader-Code als auch den agent.jardarin enthaltenen.

Die resultierende ausführbare Loader-Struktur sieht folgendermaßen aus:

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

Aus der VirtualMachine # loadAgent- Spezifikation (java.lang.String) muss ein Pfad zur JAR bereitgestellt werden , der den Agenten als ersten Parameter enthält.

Bei der Verwendung Main.class.getResource("/agent.jar").getPath()bekomme ich jedoch eine AgentLoadException: Agent JAR not found or no Agent-Class attribute. Was ist der richtige Weg, um das zu tun?

Antworten

1 davidvera Nov 15 2020 at 01:44

Ich hatte bereits ein solches Problem bei einem Maven-Projekt. Auf jeden Fall benötigen Sie möglicherweise eine Manifestdatei hier in META-INF / MANIFEST.MF:

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

Weitere Details finden Sie hier: https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.htmloder Agent JAR nicht gefunden oder kein Agent-Class-Attribut

1 user7401478 Nov 15 2020 at 17:39

Es sieht so aus, als ob die zu ladende Agenten-JAR auf der Festplatte vorhanden sein muss. Ich habe dieses Problem gelöst, indem ich die eingebettete JAR-Ressource in eine temporäre Datei kopiert habe:

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

Ich verwende dann diesen temporären Pfad, um den Agenten zu laden:

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