Laden Sie eine Java Agent JAR im Loader
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
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
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);