2016-09-30 141 views
0

我試圖按照我在之前發佈的問題中找到的一些建議,但似乎無法獲得完整的解決方案。使用以下代碼:使用代理注入CDI生產者

@Produces 
@Dependent 
@RestClientResourceConnector 
public <T> RestClientProxy<T> getStatusResource(InjectionPoint injectionPoint) throws NamingException, OAuthClientException { 
String propertiesFile = null; 
String url = null; 
AuthenticationStrategy authStrategy = null; 

Class<T> clazz = (Class<T>) ((ParameterizedType)injectionPoint.getType()).getActualTypeArguments()[0]; 

for (Annotation qualifier : injectionPoint.getQualifiers()) { 
    if (qualifier instanceof RestClientResourceConnector) { 
    RestClientResourceConnector connector = (RestClientResourceConnector) qualifier; 
    propertiesFile = connector.value(); 
    url = connector.clientUrl(); 
    LOGGER.debug("url set to: " + url); 

    authStrategy = this.createAuthStrategry(propertiesFile); 
    } 
} 

Constructor<?> constructor; 
try { 
    constructor = clazz.getConstructor(String.class, AuthenticationStrategy.class); 
} catch (NoSuchMethodException | SecurityException e1) { 
    // TODO Auto-generated catch block 
    e1.printStackTrace(); 
    return null; 
} 

try { 
    RestClientProxy rcp = new RestClientProxy(); 
    rcp.setService(constructor.newInstance(url, authStrategy)); 
    return rcp; 
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

return null; 
} 

爲限定符的來源是:

@Qualifier 
@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) 
public @interface RestClientResourceConnector 
{ 
    @Nonbinding String value() default ""; 
    @Nonbinding String clientUrl() default ""; 
} 

隨着RestClientProxy定義爲:

public class RestClientProxy<T> { 
private T client; 

public RestClientProxy() { 
} 

public RestClientProxy(T service) { 
    this.client = service; 
} 

public void setService(T service) { 
    this.client = service; 
} 

public T get() { 
    return client; 
} 
} 

並嘗試與注入:

@Inject 
    @RestClientResourceConnector(value="ferpa.properties", clientUrl="person.enpoint.url") 
    RestClientProxy<PersonResourceClient> personProxy; 

我得到了th e焊接例外:

2016-09-30 14:07:08,372 WARN [org.jboss.weld.Bootstrap] (weld-worker-1) WELD-001125: Illegal bean type javax.validation.ConstraintValidator<edu.psu.injection.validator.NotNullNotEmptyCollection, java.util.Collection<?>> ignored on [EnhancedAnnotatedTypeImpl] public class edu.psu.injection.validator.NotNullNotEmptyCollectionValidator 
2016-09-30 14:07:08,782 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC000001: Failed to start service jboss.deployment.unit."account-activation-web.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."account-activation-web.war".WeldStartService: Failed to start service 
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904) 
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:745) 
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type RestClientProxy<AccountActivationClient> with qualifiers @RestClientResourceConnector 
at injection point [BackedAnnotatedField] @Inject @RestClientResourceConnector private edu.psu.activation.services.AccountActivationTokenService.accountActivationClientProxy 
at edu.psu.activation.services.AccountActivationTokenService.accountActivationClientProxy(AccountActivationTokenService.java:0) 

at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359) 
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281) 
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134) 
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155) 
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518) 
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68) 
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66) 
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60) 
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53) 
at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
... 3 more 

2016-09-30 14:07:08,787 ERROR [org.jboss.as.controller.management-operation] (management-handler-thread - 8) WFLYCTL0013: Operation ("full-replace-deployment") failed - address: ([]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"account-activation-web.war\".WeldStartService" => "org.jboss.msc.service.StartException in service jboss.deployment.unit.\"account-activation-web.war\".WeldStartService: Failed to start service 
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type RestClientProxy<AccountActivationClient> with qualifiers @RestClientResourceConnector 
at injection point [BackedAnnotatedField] @Inject @RestClientResourceConnector private edu.psu.activation.services.AccountActivationTokenService.accountActivationClientProxy 
at edu.psu.activation.services.AccountActivationTokenService.accountActivationClientProxy(AccountActivationTokenService.java:0) 
"}} 

一如既往,任何幫助,非常感謝。

回答

1

幸運的是,答案非常簡單。

要解決您的問題,您應該在Weld比較兩個註釋實例時排除您的註釋成員(valueclientUrl)。要達到此目的,請使用@Nonbinding註釋。

import javax.enterprise.util.Nonbinding; 
import javax.inject.Qualifier; 

@Qualifier 
@Retention(RUNTIME) 
@Target({TYPE, METHOD, FIELD, PARAMETER}) 
public @interface RestClientResourceConnector { 

    @Nonbinding 
    String value() default "value"; 

    @Nonbinding 
    String clientUrl() default "clientUrl"; 
} 

詳細說明:

如果你仔細閱讀堆棧跟蹤,你可以找到某事像:

WELD-001475: The following beans match by type, but none have matching qualifiers: 
    - Managed Bean [class RestClientProxy] with qualifiers [@Any @Default], 
    - Producer Method [RestClientProxy<T>] with qualifiers [@RestClientResourceConnector @Any] declared as [[BackedAnnotatedMethod] @Produces @Dependent @RestClientResourceConnector public *your_producer_method_goes_here*... 

這意味着,焊接找到匹配的豆,但它沒有一個需要的限定符。你可能會問,「爲什麼?」。因爲你的注入點包含兩個參數限定詞:

@RestClientResourceConnector(value="ferpa.properties", clientUrl="person.enpoint.url") 

但你的生產者方法與

@Produces 
@Dependent 
@RestClientResourceConnector 

這就是爲什麼你應該告訴焊接忽略這些參數只是定義。

UPDATE

作爲用戶@ussmith發現,這個問題是由以下事實引起的,即生產者方法沒有一個CDI豆存檔內定義。

我再次發現CDI比它應該更混亂。使用明確的配置,這種問題不應該發生。

+0

感謝和道歉,我應該添加上面的限定符代碼。註釋成員已經是@Nonbinding。我已經成功地使用了與生成的實例完全相同的代碼和非泛型,所以我現在就是通用的兔子洞。 –

+0

嗯。上面的代碼對Weld ** 2.3.5.Final **完全正常。您使用哪個焊接版本?順便說一句:也請用完整的堆棧跟蹤來更新你的問題。這可能會有所幫助。 –

+0

正在運行2.2.14.Final。我會和我的操作人員討論升級問題。完整的堆棧跟蹤現在在帖子中。再次感謝。 –