我正在尝试为库Reflections
设置ConfigurationBuilder
,它使用以下配置:
我通过Maven依赖项使用库
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
的最新可用版本,0.9.10
这是我需要应用于扫描仪的3个约束:
- 在
package1
,package2
或package3
包中声明 - 类
SuperClass.class
的扩展
@Annotation1
或@Annotation2
注释的所有代码都在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>