payara / Payara

Payara Server is an open source middleware platform that supports reliable and secure deployments of Java EE (Jakarta EE) and MicroProfile applications in any environment: on premise, in the cloud or hybrid.
http://www.payara.fish
Other
882 stars 304 forks source link

@Default Dependency Injection not working in project dependencies #1893

Closed ghost closed 6 years ago

ghost commented 7 years ago

Dear guys, We had some strange issues depending on payaramicro 4.1.2.172 with dependency injection. Basically I solved the first issues of this error in local application by adding annotation of beans which would be injected. But then I got the same problem with a dependency of our application.

Vaadin-cdi-2.0.0 has a dependency to apache/deltaspike, which has the same injection problem. I requested a fix for deltaspike with https://issues.apache.org/jira/browse/DELTASPIKE-1285

Now we changed our upcoming development to use some microservices from vaadin application and used eureka-client-1.8.0 to discover the microservice instances. Unfortunatelly eureka-client-1.8.0 has the problem with dependency injection...

Disableing cdi scanning for these dependencies is not really an option, because then deployment fails due to missing injected beans sometimes.

Expected Outcome

Deployment of API successfull without exceptions.

Current Outcome

org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type EurekaInstanceConfig with qualifiers @Default
  at injection point [BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject public com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider(EurekaInstanceConfig)
  at com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider.<init>(EurekaConfigBasedInstanceInfoProvider.java:38)
  Possible dependencies:
  - Managed Bean [class com.netflix.appinfo.MyDataCenterInstanceConfig] with qualifiers [@Any @Default],
  - Managed Bean [class com.netflix.appinfo.CloudInstanceConfig] with qualifiers [@Any @Default]
        at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:370)
        at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:284)
        at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:137)
        at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:158)
        at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:501)
        at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:487)
        at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:462)
        at org.jboss.weld.bootstrap.WeldStartup.validateBeans(WeldStartup.java:454)
        at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:90)
        at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:227)
        at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
        at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:329)
        at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:497)
        at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:220)
        at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:487)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
        at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
...
Exception 1 :
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type InstanceInfo with qualifiers @Default
  at injection point [BackedAnnotatedParameter] Parameter 2 of [BackedAnnotatedConstructor] @Inject public com.netflix.appinfo.ApplicationInfoManager(EurekaInstanceConfig, InstanceInfo)
  at com.netflix.appinfo.ApplicationInfoManager.<init>(ApplicationInfoManager.java:66)
        at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:362)
        at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:284)
        at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:137)
        at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:158)
        at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:501)
        at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:487)
        at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:462)
        at org.jboss.weld.bootstrap.WeldStartup.validateBeans(WeldStartup.java:454)
        at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:90)
        at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:227)
        at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
        at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:329)
...
Caused by: org.jboss.weld.exceptions.DeploymentException: Exception List with 2 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type EurekaInstanceConfig with qualifiers @Default
  at injection point [BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject public com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider(EurekaInstanceConfig)
  at com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider.<init>(EurekaConfigBasedInstanceInfoProvider.java:38)
  Possible dependencies:
  - Managed Bean [class com.netflix.appinfo.MyDataCenterInstanceConfig] with qualifiers [@Any @Default],
  - Managed Bean [class com.netflix.appinfo.CloudInstanceConfig] with qualifiers [@Any @Default]
        at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:370)
        at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:284)
        at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:137)
        at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:158)
        at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:501)
        at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:487)
        at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:462)
        at org.jboss.weld.bootstrap.WeldStartup.validateBeans(WeldStartup.java:454)
        at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:90)
        at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:227)
        at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
        at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:329)
...
Exception 1 :
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type InstanceInfo with qualifiers @Default
  at injection point [BackedAnnotatedParameter] Parameter 2 of [BackedAnnotatedConstructor] @Inject public com.netflix.appinfo.ApplicationInfoManager(EurekaInstanceConfig, InstanceInfo)
  at com.netflix.appinfo.ApplicationInfoManager.<init>(ApplicationInfoManager.java:66)
        at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:362)
        at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:284)
        at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:137)
        at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:158)
        at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:501)
        at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:487)
        at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:462)
        at org.jboss.weld.bootstrap.WeldStartup.validateBeans(WeldStartup.java:454)
        at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:90)
        at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:227)
        at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
        at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:329)
...

We are deploying a vaadin application inside a war-file by using payara-micro-4.1.2.172. The dependencies of the gradle build project are the following.

dependencies {
    compile fileTree(dir: 'lib', include: ['*.jar'])
    // central maven repo
    testCompile('org.easymock:easymock:3.4')
    testCompile('junit:junit:4.12')
    testCompile('org.jvnet.mock-javamail:mock-javamail:1.9')
    compile('org.codehaus.castor:castor-xml:1.4.1')
    /*use commons-beanutils in updated version as dependency of some apis like slf4j and jasperreports*/
    compile('commons-beanutils:commons-beanutils:1.9.3')
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.5'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.4'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.8.5'
    compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.8.6'
    compile group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version: '2.8.6'
    compile group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.2'
    compile group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.4.5'
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.2'
    compile group: 'com.netflix.eureka', name: 'eureka-client', version: '1.8.0'
    compile group: 'com.netflix.archaius', name: 'archaius-core', version: '0.7.5'
    compile group: 'commons-configuration', name: 'commons-configuration', version: '1.8'
    compile group: 'com.google.inject', name: 'guice', version: '4.0'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.8'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.8'
    compile group: 'com.sun.jersey.contribs', name: 'jersey-apache-client4', version: '1.19'
    compile group: 'com.netflix.netflix-commons', name: 'netflix-eventbus', version: '0.3.0'
    compile group: 'com.netflix.netflix-commons', name: 'netflix-eventbus', version: '0.3.0'
    compile('com.vaadin:vaadin-compatibility-server:8.0.6')
    compile('com.vaadin:vaadin-client:8.0.6')
    compile('com.vaadin:vaadin-compatibility-client-compiled:8.0.6')
    compile('com.vaadin:vaadin-cdi:2.0.0') {
        // exclude deltaspike due to known problem with deltaspike impl described in README.MD
        exclude group: 'org.apache.deltaspike.core'
    }
    compile('net.redhogs.cronparser:cron-parser-core:2.10')
    compile('com.vaadin:vaadin-shared:8.0.6')
    compile('com.vaadin:vaadin-themes:8.0.6')
    compile('com.vaadin:vaadin-push:8.0.6')
    compile('com.vaadin:vaadin-sass-compiler:0.9.13')
    compile('com.vaadin:vaadin-widgets:7.7.10')
    compile('com.vaadin.external.slf4j:vaadin-slf4j-jdk14:1.6.1')
    compile('javax.ejb:ejb-api:3.0')
    compile('javax.inject:javax.inject:1')
    compile('javax.enterprise:cdi-api:2.0-PFD')
    compile('commons-dbutils:commons-dbutils:1.6')
    compile('org.hibernate:hibernate-core:5.2.10.Final')
    compile('org.slf4j:slf4j-api:1.7.25')
    compile('org.slf4j:slf4j-log4j12:1.7.25')
    compile('org.apache.shiro:shiro-core:1.3.2')
    compile('org.apache.shiro:shiro-web:1.3.2')
    compile('org.apache.shiro:shiro-ehcache:1.3.2')
    compile('org.apache.poi:poi:3.15')
    compile('org.apache.commons:commons-lang3:3.5')
    compile('com.jcraft:jsch:0.1.54')
    compile('net.sourceforge.barbecue:barbecue:1.5-beta1')
    compile('net.tanesha.recaptcha4j:recaptcha4j:0.0.7')
    compile('com.nulab-inc:zxcvbn:1.2.3')
    compile('com.sun.xml.rpc:jaxrpc-impl:1.1.3_01')
    // jasperreports with dependency problems
    compile('com.lowagie:itext:2.1.7')
    compile('org.olap4j:olap4j:1.2.0')
    compile('net.sf.jasperreports:jasperreports:6.4.0') {
        exclude group: 'org.olap4j', module: 'olap4j'
    }
    // xws-security with dependency problems
    compile('com.sun.xml.wsit:xmldsig:1.1')
    compile('com.sun.xml.wss:xws-security:3.0') {
        exclude group: 'javax.xml.crypto', module: 'xmldsig'
    }
    // runtime dependencies of SupplierAvailabilityService used in integratedstocksituation.jar
    runtime 'io.swagger:swagger-annotations:1.5.8'
    runtime 'com.squareup.okhttp:okhttp:2.7.5'
    runtime 'com.squareup.okhttp:logging-interceptor:2.7.5'
    runtime 'com.google.code.gson:gson:2.6.2'
    runtime 'joda-time:joda-time:2.9.3'
    runtime 'org.apache.commons:commons-lang3:3.6'
}

Steps to reproduce (Only for bug reports)

If necessary I can produce an example application to deploy, which will have the same error. If necessary please contact me. I cannot add the 120mb application of our company here. We deploy with the following call. java -jar /payara-micro.jar --logProperties /logging.properties --domainConfig /servicedata/domain.xml --deploy /app.war

Environment

MattGill98 commented 7 years ago

Hi @sredelin,

Would you be able to give a short reproducer? It might be related to which Vaadin annotations you're using, as I didn't find any problems with the following code:

@CDIUI("")
public class WelcomePage extends UI {

    @Inject
    private TestBean bean;

    @Override
    protected void init(VaadinRequest request) {
        setSizeFull();
        Label label = new Label(bean.getMessage());
        setContent(new HorizontalLayout(label));
    }

}

@RequestScoped
public class TestBean {

    public String getMessage() {
        return "Hello World! The time is: " + LocalTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME).split("\\.")[0];
    }

}

Kind regards,

Matt

ghost commented 6 years ago

actually the problem is not related to how you try to use the vaadin library. you can have an "empty" WAR file (or at least no class that has any Vaadin related code) and only include the vaadin-cdi dependency in your pom.xml, which transitively pulls in the two deltaspike jar files. this is already enough for the WAR file to be undeployable on Payara running inside Docker. It works fine OUTSIDE of a Docker container, but not inside one.

Please have a look again at the Jira ticket Sven provided in his original post, i added some information to that, outlining a workaround and some background.

The "TL;DR" is this: the deltaspike jars use the CDI 1.0 version of the beans.xml that does not explicitly specify the bean discovery mode, which SHOULD mean that discovery mode "all" is used, but instead it seems that Payara falls back to "annotated". This causes some beans in those jar files not to be discovered, because they dont have any CDI annotations and therefore cause an unresolved dependency exception during deployment.

It can be worked around by upgrading the beans.xml file to CDI 1.1+ spec and explicitly setting discovery mode to "all", then it will deploy correctly.

but the behaviour of Payara seems not to be in line with CDI spec in this case, because it should have worked with the original beans.xml file, too....and in fact, outside of a Docker container it DOES work and deploys fine in Payara!

ghost commented 6 years ago

To give you a starting point for debuggin this, include this in the pom.xml of your WAR project:

    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-cdi</artifactId>
                    <version>2.0.0</version>
    </dependency>

and then try to deploy this in Payara running inside Docker. You don't need to have any code in your project that tries to use this dependency!

smillidge commented 6 years ago

CDI 1.1 specifies annotated as the default bean discovery mode. Have you tried switching your application to have a bean discovery mode of all?

ghost commented 6 years ago

it's not the discovery mode of my application that is relevant here. the deltaspike JAR's (transitive dependency of vaadin) have their own beans.xml and they are still in CDI 1.0 format, which implies that they should be treated by Payara as using discovery mode "all" (for that one JAR) but they aren't, they are treated as is they use "annotated", but only if you are inside a docker container.

smillidge commented 6 years ago

What docker image are you using? I don't see why docker would make any difference.

struberg commented 6 years ago

Hi @smillidge

CDI 1.1 specifies annotated as the default bean discovery mode.

but only if <beans version="1.1"> or higher is specified (or the respective xsd). Without any version tag we are still in 1.0 compat mode so to say

An empty beans.xml file or a beans.xml with <beans/> or <beans></beans> still leads to 'all' mode as per CDI specs 1.1, 1.2 and even 2.0.

Otherwise the same JAR would behave totally different depending whether you run on an EE6, 7 or 8 container. Which is not what we want, right?

smillidge commented 6 years ago

true but this deploys outside of a docker container correctly but not in one which is weird.

smillidge commented 6 years ago

Can you provide a test case please if this is still an issue?

smillidge commented 6 years ago

Closing due to inactivity