简体   繁体   中英

jersey 2.0 :: for cdi injection, is beans.xml mandatory?

Resource class

public class UploadFileService {

    @Inject public Logger logger;

    @POST
    @Path("/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadFile(
        @FormDataParam("file") InputStream uploadedInputStream,
        @FormDataParam("file") FormDataContentDisposition fileDetail) {
    }
}

Injecting :: Logger class

@Dependent
public final class Loggers {

    @Produces
    public static final Logger getLogger(final InjectionPoint injectionPoint) {
    if (injectionPoint == null) {
        throw new IllegalArgumentException("injectionPoint", new NullPointerException("injectionPoint"));
    }
}

Injection perfectly works on including beans.xml at

*.war\\WEB-INF\\classes\\META-INF\\beans.xml

But is it not beans.xml optional in jersey 2.0 ?

Error reported in the absence of beans.xml

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=Logger,parent=UploadFileService,
qualifiers={},position=-1,optional=false,self=false,unqualified=null,1642832267)
        at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
        at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:947)
        at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:902)
        at org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider$CdiFactory$2.getInstance(CdiComponentProvider.java:245)
        at org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider$CdiFactory.provide(CdiComponentProvider.java:189)

Any clarification is helpful ?

The answer to your questions depends on the version of CDI .

CDI 1.0

For version 1.0 of CDI , beans.xml is mandatory to enable CDI bean discovery. Without beans.xml , CDI is simply not active in the corresponding archive.

From CDI 1.1

Starting from CDI 1.1, beans.xml is no longer mandatory. And the scanning is as follow :

  • Omitting beans.xml, or setting bean-discovery-mode="annotated" , makes the archive an implicit archive. In this case, the container will scan for beans with annotated scope types.
  • Setting bean-discovery-mode="all" , all classes will be scanned.

So in your case, if you want to make Jersey 2.0 work without beans.xml , assuming that CDI version is at least 1.1, you can annotate your Rest resource with scope, typically @RequestScoped :

@RequestScoped
public class UploadFileService {

    @Inject 
    private Logger logger;

    @POST
    @Path("/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadFile(
        @FormDataParam("file") InputStream uploadedInputStream,
        @FormDataParam("file") FormDataContentDisposition fileDetail) {
    }
}

But if you use CDI 1.0, then yes you will need beans.xml .

Yes beans.xml file is required by CDI 1.1.

The places where to put them may vary depending upon your packaging style. So if you are going to have war then beans.xml should be present in the WEB-INF folder.

For the question why is it important..

The presence of beans.xml file at the designated location facilitates the CDI container to do the classpath scanning.

The beans.xml is optional in Jersey as it uses hk2 for dependency injection. But i personally think CDI 1.1 is more robust and powerful than hk2 so we should use CDI 1.1 or better CDI 2.0 (as there are hell lot of improvements in it).

And if you are curious, please feel free to look into CDI 2.0 example(without jersey) at https://github.com/NajeebArif/CDI-2.0-Example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM