Java CDI注入抽象类

Java CDI注入抽象类,java,jakarta-ee,cdi,Java,Jakarta Ee,Cdi,我有一组代码,可以在Glassfish 3.1.2上的JDK 1.6中很好地部署和执行。但是,如果更新到Glassfish 4和JDK 1.7,则在尝试部署应用程序时会出现以下错误: org.jboss.weld.exceptions.IllegalArgumentException: WELD-001407 Cannot declare an injection point with a type variable: [BackedAnnotatedField] @Inject protect

我有一组代码,可以在Glassfish 3.1.2上的JDK 1.6中很好地部署和执行。但是,如果更新到Glassfish 4和JDK 1.7,则在尝试部署应用程序时会出现以下错误:

org.jboss.weld.exceptions.IllegalArgumentException: WELD-001407 Cannot declare an injection point with a type variable: [BackedAnnotatedField] @Inject protected com.co.ejb.web.AjaxGridServlet.sourceInstance 
at org.jboss.weld.manager.InjectionTargetFactoryImpl.createInjectionTarget(InjectionTargetFactoryImpl.java:82)
at org.jboss.weld.manager.InjectionTargetFactoryImpl.createInjectionTarget(InjectionTargetFactoryImpl.java:68)
at org.jboss.weld.manager.BeanManagerImpl.createInjectionTarget(BeanManagerImpl.java:1039)
at org.jboss.weld.manager.BeanManagerImpl.fireProcessInjectionTarget(BeanManagerImpl.java:1197)
at org.glassfish.weld.WeldDeployer.firePITEvent(WeldDeployer.java:390)
at org.glassfish.weld.WeldDeployer.fireProcessInjectionTargetEvents(WeldDeployer.java:360)
at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:212)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:328)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:493)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:537)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:546)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1423)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1500(CommandRunnerImpl.java:108)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1762)
at org.glassfish.deployment.autodeploy.AutoOperation.run(AutoOperation.java:164)
at org.glassfish.deployment.autodeploy.AutoDeployer.deploy(AutoDeployer.java:595)
at org.glassfish.deployment.autodeploy.AutoDeployer.deployAll(AutoDeployer.java:482)
at org.glassfish.deployment.autodeploy.AutoDeployer.run(AutoDeployer.java:410)
at org.glassfish.deployment.autodeploy.AutoDeployer.run(AutoDeployer.java:401)
at org.glassfish.deployment.autodeploy.AutoDeployService$1.run(AutoDeployService.java:233)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-001407 Cannot declare an injection point with a type variable: [BackedAnnotatedField] @Inject protected com.co.ejb.web.AjaxGridServlet.sourceInstance
at org.jboss.weld.bootstrap.Validator.checkFacadeInjectionPoint(Validator.java:765)
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDefinitionErrors(Validator.java:352)
at org.jboss.weld.injection.producer.InjectionTargetService.validateProducer(InjectionTargetService.java:39)
at org.jboss.weld.manager.InjectionTargetFactoryImpl.createInjectionTarget(InjectionTargetFactoryImpl.java:79)
... 24 more
有关文件包括:

BaseJasonServlet

public abstract class BaseJsonServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doProcess(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doProcess(request, response);
    }

    protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        this.process(request, response);
    }

    protected abstract void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
扩展BaseJsonServlet的AjaxGridServlet。问题在于我们在这个文件中注入了一个TSource实例

public abstract class AjaxGridServlet<TSource extends AjaxGridSource<?,?>> extends BaseJsonServlet {
    private static final long serialVersionUID = 1L;

    @Inject
    protected Instance<TSource> sourceInstance;

    @Override
    protected void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        TSource source= sourceInstance.get();
        source.process(request, response);
        response.getWriter().write(source.toJsonString());
        }
}

公共抽象类AjaxGridServlet消息告诉您的是,不能有一个带有类型变量的实例。也就是说,您不能在那里使用
TSource


您应该改用
Instance

消息告诉您的是,您不能拥有带有类型变量的实例。也就是说,您不能在那里使用
TSource

您应该改用
实例

试试看

@Inject
protected Instance<AjaxGridSource> sourceInstance;
@Inject
受保护的实例源实例;
因为反射检测到正确的运行时类型的泛型参数非常复杂。

试试看

@Inject
protected Instance<AjaxGridSource> sourceInstance;
@Inject
受保护的实例源实例;


因为反射检测到正确的运行时类型的泛型参数非常复杂。

当我更改应用程序将部署但servlet不工作时。返回org.jboss.weld.exceptions.unsatifiedResolutionException:weld-001308无法解析类型:[class com.co.ejb.web.AjaxGridSource]的任何bean;绑定:[QualifierInstance{annotationClass=interface javax.enterprise.inject.Default,values={},hashCode=-1237982948}],这意味着上下文中没有这样的bean?AjaxGridSource是一个抽象类,有30多个不同的类对其进行扩展。如果我们这样做,这是一个相当复杂的场景,我不确定你是否真的需要这样做。可能可以使用生产者来识别注入点并消除实现之间的歧义,但我觉得这通常是错误的方法;我不能建议如何改进/重构它,尽管当我更改应用程序将部署但servlet不工作时。返回org.jboss.weld.exceptions.unsatifiedResolutionException:weld-001308无法解析类型:[class com.co.ejb.web.AjaxGridSource]的任何bean;绑定:[QualifierInstance{annotationClass=interface javax.enterprise.inject.Default,values={},hashCode=-1237982948}],这意味着上下文中没有这样的bean?AjaxGridSource是一个抽象类,有30多个不同的类对其进行扩展。如果我们这样做,这是一个相当复杂的场景,我不确定你是否真的需要这样做。可能可以使用生产者来识别注入点并消除实现之间的歧义,但我觉得这通常是错误的方法;我不能建议如何改进/重构它,虽然AjaxGridSource是一个抽象类,servlet指定使用哪个源。例如,我发布的servlet使用源AdminDashboardSource。由于某些原因,它无法发现
AdminDashboard
。您是否缺少
beans.xml
?或者,如果不是这样,请尝试为抽象类创建一个生产者,我们不会缺少beans.xml。注入在应用的其他领域也起作用。此代码与EE 6和Glassfish 3.1.2一起使用,它是导致问题的EE 7和Glassfish 4的升级。CDI 1.1中是否存在不允许使用类型变量创建实例的内容。不,应该可以。正如我所说,试着找一个@Producer。Google It我们可以使用producer,但我如何在抽象类中限定它,在抽象类中,注入恰好知道我们30多个扩展AjaxGridSource的类中要使用哪一个?AjaxGridSource是一个抽象类,servlet指定要使用哪一个源。例如,我发布的servlet使用源AdminDashboardSource。由于某些原因,它无法发现
AdminDashboard
。您是否缺少
beans.xml
?或者,如果不是这样,请尝试为抽象类创建一个生产者,我们不会缺少beans.xml。注入在应用的其他领域也起作用。此代码与EE 6和Glassfish 3.1.2一起使用,它是导致问题的EE 7和Glassfish 4的升级。CDI 1.1中是否存在不允许使用类型变量创建实例的内容。不,应该可以。正如我所说,试着找一个@Producer。Google It我们可以使用producer,但我如何在抽象类中限定它,在抽象类中注入恰好知道我们30多个类中哪些扩展了AjaxGridSource以供使用?