谷歌应用引擎和Java org.反射库-扫描过程中出现错误



我正在尝试为库Reflections设置ConfigurationBuilder,它使用以下配置:

我通过Maven依赖项使用库

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.10</version>
</dependency>

的最新可用版本,0.9.10

这是我需要应用于扫描仪的3个约束:

    @Annotation1@Annotation2注释的
  • package1, package2package3包中声明
  • SuperClass.class
  • 的扩展

所有代码都在ServletContextListener中执行(如果是localhost,则触发并启动dev-server的实例)

这是我设法创建的代码

ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
// Package filter
FilterBuilder scannerFilter = new FilterBuilder();
scannerFilter.includePackage("com.mypackage1");
scannerFilter.includePackage("com.mypackage2");
scannerFilter.includePackage("com.mypackage3");
configurationBuilder.filterInputsBy(scannerFilter);
// Select the proper location to scan
configurationBuilder.setUrls(Arrays.asList(ClasspathHelper.forClass(SuperClass.class)));
Reflections reflections = new Reflections(configurationBuilder);
// Get all the classes with annotation @Annotation1 or @Annotation2
Set<Class<?>> annotation1Classes = reflections.getTypesAnnotatedWith(Annotation1.class);
Set<Class<?>> annotation2Classes = reflections.getTypesAnnotatedWith(Annotation2.class);

,但它不工作。这条线

Reflections reflections = new Reflections(configurationBuilder);

触发以下错误:

ago 26, 2015 1:22:22 PM com.google.appengine.tools.development.agent.impl.Transformer transform
GRAVE: Unable to instrument javassist.bytecode.annotation.ShortMemberValue. Security restrictions may not be entirely emulated.
java.lang.RuntimeException
    at com.google.appengine.repackaged.org.objectweb.asm.MethodVisitor.visitParameter(MethodVisitor.java:114)
    at com.google.appengine.repackaged.org.objectweb.asm.ClassReader.readMethod(ClassReader.java:959)
    at com.google.appengine.repackaged.org.objectweb.asm.ClassReader.accept(ClassReader.java:693)
    at com.google.appengine.repackaged.org.objectweb.asm.ClassReader.accept(ClassReader.java:506)
    at com.google.appengine.tools.development.agent.impl.Transformer.rewrite(Transformer.java:146)
    at com.google.appengine.tools.development.agent.impl.Transformer.transform(Transformer.java:113)
    at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
    at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:199)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at javassist.bytecode.AnnotationsAttribute.getAnnotations(AnnotationsAttribute.java:227)
    at org.reflections.adapters.JavassistAdapter.getAnnotationNames(JavassistAdapter.java:156)
    at org.reflections.adapters.JavassistAdapter.getClassAnnotationNames(JavassistAdapter.java:50)
    at org.reflections.adapters.JavassistAdapter.getClassAnnotationNames(JavassistAdapter.java:24)
    at org.reflections.scanners.TypeAnnotationsScanner.scan(TypeAnnotationsScanner.java:12)
    at org.reflections.scanners.AbstractScanner.scan(AbstractScanner.java:35)
    at org.reflections.Reflections.scan(Reflections.java:250)
    at org.reflections.Reflections.scan(Reflections.java:204)
    at org.reflections.Reflections.<init>(Reflections.java:129)
    at it.noovle.ape.core.persistence.objectify.ObjectifyManager.getClassesToRegister(ObjectifyManager.java:107)
    at it.noovle.ape.core.listener.ObjectifyServantLoader.contextInitialized(ObjectifyServantLoader.java:51)
    at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
    at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.jetty.Server.doStart(Server.java:224)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:266)
    at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:288)
    at com.google.appengine.tools.development.AutomaticInstanceHolder.startUp(AutomaticInstanceHolder.java:26)
    at com.google.appengine.tools.development.AbstractModule.startup(AbstractModule.java:87)
    at com.google.appengine.tools.development.Modules.startup(Modules.java:105)
    at com.google.appengine.tools.development.DevAppServerImpl.doStart(DevAppServerImpl.java:258)
    at com.google.appengine.tools.development.DevAppServerImpl.access$000(DevAppServerImpl.java:47)
    at com.google.appengine.tools.development.DevAppServerImpl$1.run(DevAppServerImpl.java:213)
    at com.google.appengine.tools.development.DevAppServerImpl$1.run(DevAppServerImpl.java:211)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:211)
    at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:270)
    at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
    at com.google.appengine.tools.development.DevAppServerMain.run(DevAppServerMain.java:218)
    at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:209)

我应该提到我正在做一个谷歌应用引擎项目

我也尝试从主页

提供的示例开始
//scan urls that contain 'my.package', include inputs starting with 'my.package', use the default scanners
Reflections reflections = new Reflections("my.package");
//or using ConfigurationBuilder
new Reflections(new ConfigurationBuilder()
     .setUrls(ClasspathHelper.forPackage("my.project.prefix"))
     .setScanners(new SubTypesScanner(), 
                  new TypeAnnotationsScanner().filterResultsBy(optionalFilter), ...),
     .filterInputsBy(new FilterBuilder().includePackage("my.project.prefix"))
     ...);

但是我无法创建一个工作代码。


编辑

从网站提供的示例开始(并通过使用JavaDoc),我设法创建了另一个代码

Reflections reflections = new Reflections(new ConfigurationBuilder()
        .setUrls(
                // Select the proper location to scan
                ClasspathHelper.forClass(SuperClass.class)
        )
        .setScanners(
                // Scan only the subtype of SuperClass
                new SubTypesScanner().filterResultsBy(
                        new FilterBuilder()
                            .include(SuperClass.class.getName())
                ),
                // Scan only the types which have the required annotations
                new TypeAnnotationsScanner().filterResultsBy(
                        new FilterBuilder()
                            .include(Annotation1.class.getName())
                            .include(Annotation2.class.getName())
                )
        )
        .filterInputsBy(
                // Include only 3 package in the analysis
                new FilterBuilder()
                    .includePackage("com.my.package1")
                    .includePackage("com.my.package2")
                    .includePackage("com.my.package3")
        )
);
Set<Class<?>> annotation1Classes  = reflections.getTypesAnnotatedWith(Annotation1.class);
Set<Class<?>> annotation2Classes  = reflections.getTypesAnnotatedWith(Annotation2.class);

只要我使用main方法来测试代码(我这样做是为了快速测试各种代码行,而不是每次运行App Engine开发服务器),此代码就可以工作。

但是同样的代码,由App Engine dev-server执行会触发我上面已经发布的异常错误。

然后……这个问题似乎与应用引擎服务器有关,而不是严格的反射代码。


EDIT2

确实,在扫描期间(使用App Engine环境)会抛出异常(我需要添加很多次,以至于Eclipse控制台日志不能包含所有行,它删除了最旧的行)。

但是这些异常并没有真正被抛出(catch子句将是无意义的),并且在最后扫描器提供正确的类。

在这一点上,这些异常似乎只是由Reflections构造函数抛出的严重日志,但它们并不停止服务器的执行。

这只需要理解为什么这些异常被抛出,也许它与应用引擎环境有关,它阻止了Java的一些内部特性。


EDIT3

我尝试部署应用程序,看看在生产环境中有什么样的行为。不像开发环境(它记录了很多严重的异常),在线没有任何错误记录,但扫描结果是0类。

在向项目站点打开问题后,该问题已在Google支持的帮助下得到解决,其回复为:

java运行时团队能够追踪到一个奇怪的问题javassist中格式化的类文件(javassist/bytecode/ClassFile.class)其中主版本指示Java SE 6.0,但代码似乎是

因此,强制javassist到一个完整的版本应该可以工作例如:

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.10</version>
    <exclusions>
        <exclusion>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.18.2-GA</version>
</dependency>

相关内容

  • 没有找到相关文章