首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有模块的Java工具

带有模块的Java工具
EN

Stack Overflow用户
提问于 2021-12-12 17:17:03
回答 1查看 470关注 0票数 2

我试图在一个模块化的应用程序中运行一个javaagent,但是我不能让它在命令行中工作。我已经创建了尽可能小的存储库:

代码语言:javascript
复制
.
├── Makefile
├── manifest
└── mods
    ├── main
    │   ├── module-info.java
    │   └── tsp
    │       └── App.java
    └── modifier
        ├── module-info.java
        └── tsp
            └── Agent.java

mods/main/module-info.java

代码语言:javascript
复制
module main {
}

mods/main/tsp/App.java

代码语言:javascript
复制
package tsp;

public class App {
    public static void main(String[] args) {
    }
}

mods/modifier/module-info.java

代码语言:javascript
复制
module modifier {
    requires java.instrument;
}

mods/modifier/tsp/Agent.java

代码语言:javascript
复制
package tsp;

import java.lang.instrument.Instrumentation;

public class Agent {
    public static void premain(String agentArgs, Instrumentation inst) {
    }
}

Makefile

代码语言:javascript
复制
SHELL := /bin/bash

.PHONY: clean build_main build_agent run

build_agent: clean
    echo -e "Premain-Class: tsp.Agent\nCan-Retransform-Classes: true\n" > manifest
    javac --module-path mods/modifier -d output/modifier $$(find mods/modifier -name *.java) && \
        jar --create --file output/modifier.jar --manifest manifest -C output/modifier .

build_main: clean
    javac --module-path mods/main -d output/main $$(find mods/main -name *.java)

run: build_main build_agent
    java -javaagent:output/modifier.jar --module-path output/main --module main/tsp.App

clean:
    rm -rf output

manifest是从Makefile自动创建的。

当我执行make run时,输出是:

代码语言:javascript
复制
rm -rf output
javac --module-path mods/main -d output/main $(find mods/main -name *.java)
echo -e "Premain-Class: tsp.Agent\nCan-Retransform-Classes: true\n" > manifest
javac --module-path mods/modifier -d output/modifier $(find mods/modifier -name *.java) && \
        jar --create --file output/modifier.jar --manifest manifest -C output/modifier .
java -javaagent:output/modifier.jar --module-path output/main --module main/tsp.App
Exception in thread "main" java.lang.ClassNotFoundException: tsp.Agent
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:431)
        at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:525)
*** java.lang.instrument ASSERTION FAILED ***: "result" with message agent load/premain call failed at open/src/java.instrument/share/native/libinstrument/JPLISAgent.c line: 422
FATAL ERROR in native method: processing of -javaagent failed, processJavaStart failed
make: *** [Makefile:14: run] Aborted (core dumped)

相反,当我将run目标在Makefile中更改为:

代码语言:javascript
复制
run: build_main build_agent
    java -javaagent:output/modifier.jar --class-path output/main tsp.App

一切都很完美。我不想使用像Gradle或Maven这样的构建工具,因为我想了解为什么它不能从命令行工作。我读过加载代理类和代理类可用的模块/类,但对我来说还不完全清楚。我做了很多尝试,比如使用--add-modules output/modifier,但都没有成功。

代码语言:javascript
复制
> java --version

openjdk 15.0.2 2021-01-19
OpenJDK Runtime Environment (build 15.0.2+7-27)
OpenJDK 64-Bit Server VM (build 15.0.2+7-27, mixed mode, sharing)
EN

回答 1

Stack Overflow用户

发布于 2021-12-12 17:50:55

代理不能是模块化的,它们会自动加载到系统类加载器的类路径中,进入未命名的模块。

我假设JVM没有正确地涵盖代理在试图调用它时是模块化并在内部崩溃的情况。

你试过用最近的Java 11/17吗?我假设可以通过删除代理的模块描述符来修复这个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70325896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档