Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Registering resources in ResourceConfig leads to warnings #3700

Closed
jerseyrobot opened this issue Oct 17, 2017 · 22 comments
Closed

Registering resources in ResourceConfig leads to warnings #3700

jerseyrobot opened this issue Oct 17, 2017 · 22 comments

Comments

@jerseyrobot
Copy link
Contributor

Hi,

we register Resources using the ResourceConfig.register(Object object) method. This works and has worked until now. However now (2.26) we are getting a warning:

Oct 17, 2017 1:47:00 PM org.glassfish.jersey.internal.inject.Providers checkProviderRuntime WARNING: A provider war.HelloWorldResource registered in SERVER runtime does not implement any provider interfaces applicable in the SERVER runtime. Due to constraint configuration problems the provider war.HelloWorldResource will be ignored.

It looks like the check assumes that no resources are registered in this way. Is this a bug or are we misusing the ResourceConfig API?

I've attached a minimal reproducing case based on the jersey-example-java8-webapp archetype. Running war.App leads to the warning above.

Thanks & best regards,
Silvestre

@jerseyrobot
Copy link
Contributor Author

@retog Commented
Same issue after updating from jersey 2.25.1 to 2.26.

@jansupol does your "question" label imply that this is not a bug but the expected behaviour? Could you explain?

@jerseyrobot
Copy link
Contributor Author

@jansupol Commented
Jersey started to provide more warnings lately, so it is possible that users can see more warnings than in the previous versions. The question in the issue description suggested you did not feel strongly about the issue, but if you now feel this is positively a bug, I am happy to change the label for you.

@jerseyrobot
Copy link
Contributor Author

@unclejamal Commented
I agree with Silvestre. I find it a huge plus of Jersey that it allows for manual dependency injection. I also would like the warning to go away if possible please.

@jerseyrobot
Copy link
Contributor Author

@electrum Commented
Has anyone found a workaround for this?

@jerseyrobot
Copy link
Contributor Author

@jvissers Commented
Question: from the text it is not clear to me whether this is just a warning - or whether things actually break. Which is it?

@jerseyrobot
Copy link
Contributor Author

@retog Commented
@jvissers it is just a warning. For me its a reason to stay with the older version as I don't want to clutter the output with this pointless warnings.
@electrum, you could try to hack into the logger or use Java.lang.System.setErr() to specifically suppress these warnings.

@jerseyrobot
Copy link
Contributor Author

@Cousjava Commented
If you want to stop it showing the messages you can set in your logger settings org.glassfish.jersey.internal.inject.Providers=SEVERE to stop it appearing

@jerseyrobot
Copy link
Contributor Author

objecttrouve added a commit to objecttrouve/jersey-1 that referenced this issue May 4, 2018
The predicate that tells if a component class is "correctlyConfigured" only checked the 'resourceClasses' collection to determine whether the resource is actually a resource.
As a consequence a warning, was logged when an instantiated resource class was tested:

"WARNING: A provider war.HelloWorldResource registered in SERVER runtime does not implement any provider interfaces applicable in the SERVER runtime. Due to constraint configuration problems the provider war.HelloWorldResource will be ignored."

The fix is as conservative as possible.
Changed the result of the relevant predicate only in the context where the changed result values should not have any impact.
But the side-effect of logging a warning should go away.

No additional test since the change shouldn't have any observable effect other than the absence of a warning.
@Tibor17
Copy link

Tibor17 commented Jul 10, 2018

Can you pls test this commit and push it to master? The dropwizard project wants to have a fix, see dropwizard/dropwizard#2418, dropwizard/dropwizard#2395

@bcalmac
Copy link

bcalmac commented Jul 27, 2018

The same is true about spring-boot.

@jansupol
Copy link
Contributor

jansupol commented Aug 1, 2018

@Tibor17 We cannot merge unless the commit contains the sign-off, I am sorry.

@serhiypal
Copy link

@jansupol how do we get a sign-off?

@jansupol
Copy link
Contributor

@serhiypal git commit -s. Please see the wiki.

@serhiypal
Copy link

@jansupol. Ah, thanks. Then what about this one: #3918.
It looks pretty similar to what is in objecttrouve@f81ab99 but is more accurate replication of missing logic from ApplicationHandler

@senivam
Copy link
Contributor

senivam commented Aug 22, 2018

The behavior of Jersey in that case seems to be correct (described issue is not a bug)

Jersey supports 2 ways of components registration - Class based registration and Instance based registration. When the class based registration is used the life-cycle of components is fully managed by the JAX-RS implementation or any underlying IoC container supported by the implementation.

On the other hand when the instance based registration is used the life-cycle of providers registered using this instance-based register(...) is not managed by JAX-RS runtime.

That is the reason why the HelloWorldResource instance is not recognized as a resource. It is expected to implement some Provider interface (which is noted in the WARNING). However it still works because the registration is valid even though it did not pass through JAX-RS IoC.

But for resources which are not going to be providers nor features (not implement those interfaces) there is class based registration which shall be called like register(HelloWorldResource.class) (and not register(new HelloWorldResource()) ). In that case the component is supposed to be a resource and no WARNING occurs.

@serhiypal
Copy link

@Tibor17 it appears the WARNING is expected, so dropwizard should be adopted to slightly changed behavior

@senivam
Copy link
Contributor

senivam commented Aug 23, 2018

Extract from Jersey API documentation (Configurable.class):

  • Registered custom JAX-RS component classes and instances are important part of the contextual configuration information as these are the main factors that determine the capabilities of a configured runtime.
  • Implementations SHOULD warn about and ignore registrations that do not conform to the requirements of supported JAX-RS components in a given configurable context.

Closing the issue as not a bug, the framework works as designed.

@bcalmac
Copy link

bcalmac commented Sep 25, 2018

@senivam We use Jersey with spring-boot and we have the resources as Spring beans. Then we register the resources with Jersey using ResourceConfig.register(Object). It would not be possible for us to register them as a class because then Jersey would create a separate instance without the right dependencies.

If the WARN points out the wrong way, what is the idiomatic way of registering resources managed by an external container?

@senivam
Copy link
Contributor

senivam commented Sep 26, 2018

@bcalmac there is a PR #3820 which provides implementation for that. However it is not merged for now (because not all requirements are completed, after that it is going to be merged). So in short when you are required to register a resource by instance it would be preferable to do as

final ResourceConfig resourceConfig = new ResourceConfig(); resourceConfig.registerResources(Resource.from(ServiceOneImpl.class, serviceOne, false)); return new ApplicationHandler(resourceConfig);

but because it is not merged yet (thus is not implemented) you can still use instance registration with warning but as soon as it is merged and released it would be preferable to modify your code accordingly

@bcalmac
Copy link

bcalmac commented Sep 26, 2018

I investigated some more the registration by class in a Spring Boot application and I'll leave my findings here for people that might be wondering how this works.

Spring Boot does recommend registering the resources by class: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-jersey

@Component
public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(Endpoint.class);
    }
}

How does this work though? How would Jersey invoke the actual Spring bean at runtime? The answer is that Jersey doesn't instantiate the resource class. Instead, SpringComponentProvider from the jersey-spring4 module creates a binding between the resource class and the Spring bean. At runtime, Jersey uses this binding to resolve the resource instance from the Spring context.

@josephlbarnett
Copy link

@bcalmac The above linked dropwizard PR (dropwizard/dropwizard#2463) does instance registration by registering an AbstractBinder implementation that binds the instance to its class. Not sure if that's truly idiomatic, but something similar could work for spring-boot.

@bric3
Copy link

bric3 commented Jun 17, 2019

@bcalmac Since Jersey 2.26 and Spring Boot 2, Spring can manage the lifecycle of the endpoints. Although I'm not sure jersey-spring4 can manage providers at this time. As said in their release note in Jersey 2.26, while the APIs are available the rest is still work in progress.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants