Spring Boot Jersey Autconfiguration - java

I want to start a new project using Spring Boot and Jersey. I have read numerous tutorials on how to do this, but one thing still puzzles me. Why do I have to register all my Jersey resources?
As an example, Lokesh Gupta has written a tutorial at https://howtodoinjava.com/spring-boot/spring-boot-jersey-example/#jersey-config where he has the following code:
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
#Component
public class JerseyConfig extends ResourceConfig
{
public JerseyConfig()
{
register(UserResource.class);
}
}
I don't want to register all my resources this way. Is there a way to get the resources to be picked up by Jersey's resource scanner? Using the method above, will the #Provider annotation of Jersey be honored? Is it possible to set the jersey.config.server.provider.packages servlet parameter somewhere?
To sum it all up: "How can I autoconfigure Jersey using Spring Boot?"

If you read in the Spring boot documentation JAX-RS and Jersey
Jersey’s support for scanning executable archives is rather limited.
For example, it cannot scan for endpoints in a package found in a
fully executable jar file or in WEB-INF/classes when running an
executable war file. To avoid this limitation, the packages method
should not be used, and endpoints should be registered individually by
using the register method, as shown in the preceding example.
So if you want an executable jar/war file then the answer is no.

Related

not able to get the bean which is created in another 3rd party spring boot lib

I have a spring boot app in which I have added another library (in pom.xml).
This library is also a spring boot library which has created some beans and made the beans available using #Bean. The code snippet in 3rd party library is like this :
#Bean
public CustomObject customObject() {
return new CustomObject();
}
Now, I am using this library in my application, but I dont see this bean registered with my application.
I checked all the beans registered with application Context and also tried loading from application context. But no luck.
What am I missing here? The purpose of this 3rd party library is to check some config and create this bean, so if I have to manually create this bean, it takes away the whole purpose.
This is information is not enough, can you please share your pom file of library that contains CustomObject.
I need to see pom file build section code.
as suggested by #Rohit in comments, I missed to add the package of the class in the 3rd party lib jar under component scan. After adding the package under component scan, issue is resolved.

How can I use a rest controller from a different package in Spring?

What's going on
I am using Java, Springboot
I am trying to create a simple API.
I have a package called Example.
I have two sub-packages called config and rest.
In config is the class Application, which is my spring app.
In rest is the class TheController which is the rest controller
Currently when i run the app, Application and try and go to one of the get mappings i get a white label error page.
However if i move theController to the config package i do not get this error and it's plain sailing.
What I have tried
I have tried using an import statement.
com.Example.rest.* and com.Example.rest.TheControllerwith no results.
Any help would be appreciated :)
Add a #ComponentScan on your application class.
package com.example.config;
#SpringBootApplication
#ComponentScan(basePackages = "com.example")
public class SpringBootComponentScanApp {
}
I personally think it's a good idea to put your configuration in a sub-package "com.example.config" and not in the parent package "com.example", but you need to override Spring Boot's default component scan for that case.
See also https://www.baeldung.com/spring-component-scanning
Spring Boot will only scan for components (controllers, services, repositories, ...) starting from the package of the application class (annotated with #SpringBootApplication) and below.
So best to use com.example.Application, then you can use com.example.rest.TheController and things should work.

Is it possible to resolve REST end points of a dependency JAR file in spring Boot

I have a 2 Spring boot jars which work fine as 2 independent applications, however, I have been asked to merge 2 jars into a single application
The easiest thing I thought would be to add app-2 as a maven dependency into app-1 but the problem is that when the app-1 starts it only recognises the app-1 REST endpoints but ignores REST endpoint of app-2 altogether.
I was hoping that when the app-1 starts it will automatically pick the endpoints declared in app-2
#RestController
Class2{
#GetMapping(/hello-from-app2)
public String myapp2(){
return "HELLO FROM APP2"
}
This code gets ignored and at server start up I can only see the endpoints exposed by app-1 are visible.
If you are including App2.jar as a dependency into App1.jar, the best approach would be to import the Configuration of App2. If you start adding scans and stuff you would be tightly coupling you App1 to your App2. App1 would have to know implementation details of App2 that doesn't need to.
If you just import the configuration of App2, the configuration details would remain encapsulated.
I assume you have a Java Config class (or an XML Config file) for App1 and another one for App2. I also assume that the config of App2 contains all the necessary annotations for component scanning and the correct base-packages.
If that's the case, you can add an import like this and it should work right away:
#Configuration
#Import(SpringConfigurationApp2.class)
public class SpringConfigurationApp1 {
//... some beans....
}
I saw answer provided by #Diego but with that user need to make changes in client application. (ex. #Import(SpringConfigurationApp2.class) here).
I have another approach where client (App-1) does not need to make any change in application. It will just work seamlessly. This approach is by use of spring's auto configuration and same feature is used by spring-boot dependency.
Here is my answer to achieve using autoconfiguration.
For App-2,
1) create spring.factories file under resources/META-INF
2) Add org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
path-to-app-2-application/SpringConfigurationApp2
For App-1,
Just include App-2 as maven dependency and you are Done.
Here is a link to get more information about https://dzone.com/articles/what-is-spring-boot-auto-configuration.

Spring Boot: Determining what autoconfiguration are applied to jersey?

Following the online docs for adding jersey to Sring boot, it appears I just need to include the following package
spring-boot-starter-jersey
Actually, it states that Spring Boot provides automatic configuration by including this package.
Where can I find out what exactly is happening?
If I don't add this package then what is NOT configured?
I tried searching for the package in google but got no specific explanation only saying that it automatically configures, but configures what?
I would like to know a little more of what is happening behind the scenes.
All of the auto-configuration code for all that Spring Boot supports is in the spring-boot-autoconfigure module. If you look through the packages, you will see a jersey package.
The "starter" modules generally do not have any code (of course unless it is a third-party module). How it works is that the code in the auto-configuration has some annotations that are #ConditionalOnXxx, where the condition be anything from a class being on the classpath. If this class is not available, then the auto-configuration will not take place. That's pretty much all adding the jersey starter module does: it adds the jersey dependencies so that the auto-configurer will applied.
Now what exactly is being auto-configured specifically for Jersey? Check out the source for the JerseyAutoConfiguration. Basically what you are going to see is your ResourceConfig being injected into the configurer. From that ResourceConfig, it creates Jersey's ServletContainer (which is the main entry point for Jersey.
Then, depending on our properties configuration, either a FilterRegistrationBean or a ServletRegistrationBean is created as a Spring bean, wrapping Jersey's ServletContainer. Jersey can be created as a Servlet or a Servlet Filter. Whichever one we configure we be used.
And that's it for the Jersey configuration. Spring Boot will get a servlet container (e.g. Tomcat, Jetty) from some other auto-configuration, and take the Filter/ServletRegistrationBean and add the Servlet/Filter to that servlet container.
Also, not really that important, but the auto-configuration also give us some Jackson configuration helpers. For example, instead of configuring our own ContextResolver, we can just configure an ObjectMapper Spring bean.
That's really all you get. It's nothing so spectacular that you couldn't just do it yourself without depending on the auto-configuration.
I would recommend learning a little more about how Spring Boot works to provide the automatic configuration in general.
A good reference is the spring boot reference guide. http://docs.spring.io/spring-boot/docs/1.5.3.RELEASE/reference/htmlsingle/#common-application-properties
You can look at the common application properties in appendix A to see what all spring allows you to configure out of the box.
The Reference guide also gives a high level of what "spring-boot-starter-jersey" if you search for it on the page.
They also have a few samples that you can go through and debug to follow along if that is a way for you to learn.
Hope that gives you a starting point for learning!

Using a Java written #Controller in Grails

I have created a Java class in Groovy Project in src/java folder.
I have used #Controller annotation to create a REST Webservice.
Code look like this
and then I configured component in resources.groovy
xmlns context: 'http://www.springframework.org/schema/context'
context.'component-scan'('base-package': 'com.**.**')
which matches package of the above piece of code.
When I'm trying to invoke service using URL its not able to recognize this.
Component scanning is already enabled by Grails, so delete yours. If you want annotated Spring beans to be discovered and registered, add one or more package names to the grails.spring.bean.packages list in Config.groovy, e.g.
grails.spring.bean.packages = ['com.foo.bar', 'some.other.package']

Categories