gpt4 book ai didi

java - 在 Tomcat Servlet 中调用时,getAnnotations() 不返回 "external"注释

转载 作者:行者123 更新时间:2023-11-28 22:16:41 24 4
gpt4 key购买 nike

我们在 Web 应用程序中使用 Tomcat 8.5 和 Jersey 2,该应用程序使用类似于此处发布的 InMemoryCompiler 编译 Java 代码:https://stackoverflow.com/a/33963977/2556413

我创建了一个最小示例:

public static void main(String[] a) throws Exception {
new TemporaryCodexExerciseCreatorWebService().test();
}

@GET
@Path("test")
public String test() throws Exception {
final String source = "package minimal_example;" +
"import org.junit.Test;" +
"import static org.junit.Assert.*;" +
"import java.lang.annotation.*;" +
"@Documented\n" +
"@Retention(value=RetentionPolicy.RUNTIME)\n" +
"@Target(value=ElementType.METHOD)\n" +
"@interface MinimalAnnotation { }\n" +
"public class MinimalExample {" +
" @Test\n" +
" @MinimalAnnotation\n" +
" public void testTrivial() {" +
" assertTrue(true);" +
" }" +
"}";
List<JavaClass> sourceCodeList = Collections.singletonList(new JavaClass("minimal_example.MinimalExample", source));

InMemoryCompiler compiler = InMemoryCompiler.compile(sourceCodeList);
CompilerFeedback compile = compiler.getCompilerFeedback();

if (!compile.isSuccess()) {
throw new RuntimeException("Compilation failed: " + compile.getMessages());
}

Class<?> compiledClass = compiler.getCompiledClass("minimal_example.MinimalExample");

Method[] methods = compiledClass.getMethods();
for (Method m : methods) {
Annotation[] annotations = m.getAnnotations();

System.err.println(m.getName() + ": " + Arrays.toString(annotations));
}

return null;
}

如果我在命令行上使用 java 解释器调用程序,我会正确收到类似 testTrivial: [@org.junit.Test(timeout=0, expected=class org.junit.Test$None) , @minimal_example.MinimalAnnotation()].

但是,如果我使用 Web 端点(“/test”)执行该方法,我只会得到我的 MinimalAnnotation 而不会返回来自 JUnit 的 Test 注释。

为什么会这样?我需要这个才能在内存中编译后以编程方式执行单元测试(我已经看到了 java.lang.Exception: No runnable methods exception in running JUnits ,但不认为我的问题与此有关,因为如果代码未在服务小程序)。

更新:实际上,我和这里的线程启动器有同样的问题:field.getAnnotations() returns empty array when run on a tomcat server, but returns correct annotation when run as a standalone但没有人知道如何修复它

更新:我通过使用类路径将 JUnit 添加为依赖项来稍微修改 InMemoryCompiler:

List<String> options = Arrays.asList("-cp", "C:\\libraries\\junit-4.12.jar;C:\\libraries\\hamcrest-core-1.3.jar");

// this is where I pass the previously created options List
final JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, diagnostics, options, null, files);

更新:我创建了一个 GitHub 存储库作为展示:https://github.com/dhardtke/tomcat-8-5-annotation-issue只需通过 Tomcat 部署它(在通过 Gradle 解决依赖关系之后),您将在调用“/compile”时看到输出不正确。

最佳答案

我终于想出了解决这个问题的方法:

在我的 InMemoryCompiler 类中,我创建了一个 JavaFileManager 对象并创建了一个 SecureClassLoader。

在我修复之前,我返回 null 以防 InMemoryCompiler 未编译的类的类名被传递。现在,在这种情况下,我将 .findClass() 调用委托(delegate)给父 ClassLoader。

您可以在我的 GitHub 存储库中找到修复后的代码。

关于java - 在 Tomcat Servlet 中调用时,getAnnotations() 不返回 "external"注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44864100/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com