在 Java8 我无法继承和覆盖继承的注释

On Java8 I cannot inherit an overriden inherited annotation

我有注释

@Qualifier
@Inherited
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface InheritedQualifier {
     public String value();
}

并且我有四个 classes 使用它。

所有四个 classes 还实现了具有唯一名称的 @Named。最后我有第五个 class 注入如下:

@Inject @InheritedQualifier("original") @Named("parent") Parent parent;
@Inject @InheritedQualifier("original") @Named("child") Child child;
@Inject @InheritedQualifier("override") @Named("grandChild") GrandChild grandChild;
@Inject @InheritedQualifier("override") @Named("greatGrandChild") GreatGrandChild greatGrandChild;

奇怪的是。当我在 Oracle 的 Java7 上 运行 它工作正常。当我 运行 它在 Java8 上时,它无法注入 GreatGrandChild。这是错误消息:

javax.enterprise.inject.UnsatisfiedResolutionException: Api type [com.ibm.ws.fat.jcdi.inheritance.GreatGrandChild] is not found with the qualifiers 
Qualifiers:[@javax.inject.Named(value=greatGrandChild),@com.ibm.ws.fat.jcdi.inheritance.InheritedQualifier(value=override)]
for injection into Field Injection Point, field name :  greatGrandChild, Bean Owner : [MyBean, Name:myBean, WebBeans Type:MANAGED, API Types:[com.ibm.ws.fat.jcdi.inheritance.MyBean,java.lang.Object], Qualifiers:[javax.enterprise.inject.Default,javax.enterprise.inject.Any,javax.inject.Named]]
at org.apache.webbeans.util.InjectionExceptionUtils.throwUnsatisfiedResolutionException(InjectionExceptionUtils.java:77)
at org.apache.webbeans.container.InjectionResolver.checkInjectionPoints(InjectionResolver.java:193)
at org.apache.webbeans.container.BeanManagerImpl.validate(BeanManagerImpl.java:1031)
at org.apache.webbeans.config.BeansDeployer.validate(BeansDeployer.java:444)
at org.apache.webbeans.config.BeansDeployer.validateInjectionPoints(BeansDeployer.java:383)
at org.apache.webbeans.config.BeansDeployer.deploy(BeansDeployer.java:184)
at org.apache.webbeans.lifecycle.AbstractLifeCycle.startApplication(AbstractLifeCycle.java:155)
at org.apache.webbeans.web.lifecycle.WebContainerLifecycle.startApplication(WebContainerLifecycle.java:97)
at com.ibm.ws.webbeans.WebBeansInitializer.onStartup(WebBeansInitializer.java:70)
at com.ibm.ws.webcontainer.webapp.WebApp.initializeServletContainerInitializers(WebApp.java:2485)
at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:1038)
at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:6404)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApp(DynamicVirtualHost.java:446)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.createRunnableHandler(DynamicVirtualHost.java:248)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.createRunnableHandler(DynamicVirtualHost.java:313)
at com.ibm.ws.http.internal.VirtualHostImpl.discriminate(VirtualHostImpl.java:251)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.ready(HttpDispatcherLink.java:306)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:449)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleNewRequest(HttpInboundLink.java:383)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.processRequest(HttpInboundLink.java:283)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.ready(HttpInboundLink.java:254)
at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:174)
at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:83)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.requestComplete(WorkQueueManager.java:504)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:574)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.workerRun(WorkQueueManager.java:929)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker.run(WorkQueueManager.java:1018)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)

其他三个注入工作正常。

我运行在 IBM Websphere Liberty Profile 上安装此应用程序。

有谁知道为什么此代码不能从 Java7 移植到 Java8?

这个linkTroubleshooting contexts and dependency injection

表明您有某种 class 路径问题。您已经说过,当您在 java 7 中 运行 时,应用程序工作正常,但在 java 8 中则不然。执行环境的区别只是使用的JVM吗?例如,您对 运行 带有 java 8 的程序所做的唯一更改是将相同的 Liberty Profile 指向不同的 JVM?

如果不是这种情况,则很可能是两个执行环境之间存在差异,而不是两个不同的 JVM。

但是,您在评论中提到唯一的变化是 JAVA_HOME 环境变量。因此,您可能只是遇到了一个可能的应用程序框架错误,或者 java 本身的错误。

我现在的建议是:

如果它不适用于 java 8,请避免使用它。 Java 8 有点新,不到一年。对于服务器使用,它是一个婴儿......顺便说一下,最新的Websphere规范只支持java 6或7......查看:Websphere 8.5.5 requirements - java

java 7 和 java 8 之间存在已知的不兼容性,也许您刚刚间接地解决了其中一个问题: incompatibilities between java 7 and 8- oracle doc

原来这是应用服务器的一个bug;它现在已经被修补了。