How to set up a Jersey init param? - glassfish

I need to set up the jersey.config.server.response.setStatusOverSendError configuration to true.

Setting Jersey properties in a JAX-RS application is possible by providing an overridden method getProperties() in a custom Application class, like in this example in Jersey tests:
public class MyApplication extends Application {
#Override
public Map<String, Object> getProperties() {
return new HashMap<String, Object>() {{
put("jersey.config.server.response.setStatusOverSendError", true);
}};
}
}
The same thing should be possible with an init-param of the Jersey servlet in web.xml, like in this Jersey test app:
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>org.glassfish.jersey.tests.integration.servlettests</param-value>
</init-param>

Related

Jersey 2 and Spring Boot - Not able to inject using #Context on Provider

Using Jersey 2.3 on Spring Boot 2.4. I have 2 JAX-RS providers. One of them implements ContainerRequestFilter(PreMatching) and another one extends JacksonJaxbJsonProvider(from jackson-jaxrs-json-provider).
I am setting a property in ContainerRequestFilter onto ContainerRequestContext. Then I am trying to inject ContainerRequestContext onto another JAX-RS Provider using #Context. But this injection is always coming null.
If I inject same object onto a JAX-RS resource using #Context, Jersey does inject it. Not sure what I am missing here. Any help is greatly appretiated.
#PreMatching
#Provider
public class MyJaxRSContextProvider implements ContainerRequestFilter {
#Context
Providers providers;
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
requestContext.setProperty("myProperty", property);
}
}
#Provider
#Consumes(MediaType.WILDCARD)
#Produces(MediaType.WILDCARD)
public class MyJsonJaxRSProvider extends JacksonJaxbJsonProvider {
#Context
ContainerRequestContext requestContext;
#Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
}
#Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
//requestcontext is always null
requestContext.getProperty("myProperty");
}
}
Things to consider:
In some cases, if you register the provider as an instance, then injection may not occur. Best thing to do is to register the provider as a class or just use scanning provided by Jersey.
Some injectables are not proxiable, which will prevent smaller scoped services to be injected into larger scoped serviced (example: request scoped object into a a singleton). In this case, you should wrap the injection in javax.inject.Provider
#Inject
private javax.inject.Provider<ContainerRequest> requestProvider;
...
ContainerRequest request = requestProvider.get();

Google guice inject a instance created by Spring and method intercept

I use Gucie 3.0 to intercept any methods that have my defined annotation #LogRequired. However for my application, some beans are initialized by Spring with injected fields values. After calling giuce injector.injectMembers(this), the beans gets proxied by guice but all original fields values are gone. Looks like Guice re-constucts the beans and throw away all old values. Is this expected behavior or how can I solve this issue?
Create a class extends AbstractModule
public class InterceptorModule extends AbstractModule{ public void configure()
{ LogInterceptor tracing = new LogInterceptor(); requestInjection(tracing); bindInterceptor(Matchers.any(), Matchers.annotatedWith(LogRequired.class), tracing); }
}
Define the interceptor business logic
public class LogInterceptor implements MethodInterceptor { //business logic here }
Create LogService class
Public class LogService { Injector injector = Guice.createInjector(new InterceptorModule()); }
I have one of the bean example below with the getName method wants to be intercepted:
public class UserImplTwo implements IUser {
private String name;
#LogRequired
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
which is initialized by Spring context:
Finally I have a consumer to consume the bean:
public class Consumer
{
#Inject
private UserImplTwo instance;
public void setInstance(UserImplTwo instance)
{
this.instance = instance;
}
public void init()
{
// the value of name is printed out as 'hello world'
System.out.println( this.instance.getName());
LogService.injector.injectMembers(this);
// the value of name is printed out as null, should be 'hello world'
System.out.println( this.instance.getName());
}
}
Then use Spring to initialized the bean:
<bean id="consumer" class="com.demo.Consumer" init-method="init">
<property name="instance" ref="userTwo"></property>
</bean>
Please let me know if this the the right approach or if I did something wrong, because I have to use Spring to initialize some beans.
A "right approach" is probably to keep things simple and use Spring's DI if you use Spring Framework, and not try to mix and match with Guice :-)
Having said that there seems no technical reason why they can't be mixed and matched together to some degree.
I think you will have more success with another approach. One that I have used before is to make use of Spring MVC Java-based configuration. Here is the basic approach.
Create a class that extends WebMvcConfigurationSupport:
#Configuration
#Import(BeansConfig.class)
public class Config extends WebMvcConfigurationSupport {
}
Separate out your beans config (probably it can be merged with the above but I guess it's quite dull code and you normally don't want want to see it). And use it to create your beans with your Guice injector before providing them to Spring.
#Configuration
public class BeansConfig {
#Bean
public Consumer getConsumer() {
return SomeGuiceInjectorFactory.newInstance(Consumer.class);
}
}
Include this in your spring.xml (or bootstrap other ways if your servlet container is newer than mine was)
<context:annotation-config/>
<bean id="extendedWebMvcConfig" class="Config"/>
Constructor injection and most/all? other Guice goodness should work also with such scenario.
Also you won't need to configure your beans in xml.

Can I make a filter initialize after the servlet?

I have a web application using spring, in which I have a servlet that locads the context in its init method:
private ContextLoader contextLoader;
public void init() throws ServletException {
contextLoader = new ContextLoader();
contextLoader.initWebApplicationContext(getServletContext());
}
In addition, I have a servlet in which I do the following:
public void init(FilterConfig config) throws ServletException {
WebApplicationContext context =
WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
//here I'm using the context
}
The problem: the filter's init() method is called before the servlet initializes, so the context I get in the filter is null. In the web.xml my servlet is configured with load-on-startup=1.
Is there any way I can make my filter initialize after the servlet initializes so that I'll be able to use the WebApplicationContext in the filter?
Thanks!
Try this:
Don't configure the filter in the web.xml
In your servlet, get the ServletContext.
Call ServletContext.addFilter() to add your filter.

EJB 3.1 : Singleton bean not getting injected inside another stateless bean though both beans are getting registered

Here is my bean that is trying to inject a singleton bean InformationService :
#Path("/information/{name}")
#Stateless (name="InformationResource")
public class InformationResource {
#EJB
private InformationService appService;
#GET
#Produces(MediaType.APPLICATION_XML)
public Information getInfo(#PathParam("name") String name){
return appService.getMap().get(name);
}
#PUT
#POST
#Consumes(MediaType.APPLICATION_XML)
public Information putInfo(#PathParam("name") String name, Information info){
return appService.getMap().put(name,info);
}
#DELETE
public void deleteInfo(#PathParam("name") String name){
appService.getMap().remove(name);
}
}
This is the InformationService class
#Singleton
public class InformationService {
private Map<String,Information> map;
#PostConstruct
public void init(){
map = new HashMap<String,Information>();
map.put("daud", new Information("B.Tech","Lucknow"));
map.put("anuragh", new Information("M.Sc","Delhi"));
}
public Map<String,Information> getMap(){
return map;
}
}
Its part of a very simple JAX-RS implementation and I am deploying as war in JBoss 6.1 Final. The problem is that InformationService throwing a NullPointerException when I make the proper get request. If I initialize appService explicitly, everything works fine. Why is #EJB annotation not working ?
Are you using Jersey as REST implementation? If so, EJB injection is not supported out of the box.
This link provides more information on this and also a solution.
Check that your #Singleton is javax.ejb.Singleton.
Any other exceptions before NPE ?

Guice not working as expected (with Tomcat, Jersey...)

I'm trying to build an app using Jersey, Rest, Tomcat, c3p0 etc.
I have a ConfigurationManager class I want to be an eager singleton, and Connection pool class I also want to be an eager singleton. Connection pool is using a Configuration Manager annotated with inject but configuration manager inside Connection pool is null, it's not injected for some reason. It's instantiated by guice I can see this from log.
When I inject it in Rest resource class it is working as expected.
Also when I inject it in StartupServlet it's null.
I would very much appreciate it if anyone can shed some light on this. Below you can find web.xml and classes.
web.xml
<servlet>
<servlet-name>StartupServlet</servlet-name>
<servlet-class>net.nemanjakovacevic.ft1p.configuration.StartupServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- set up Google Guice Servlet integration -->
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>net.nemanjakovacevic.ft1p.configuration.GuiceServletConfiguration</listener-class>
</listener>
GuiceServletConfiguration.java
public class GuiceServletConfiguration extends GuiceServletContextListener {
#Override
protected Injector getInjector() {
return Guice.createInjector(new GuiceConfigurationModule(), new JerseyServletModule() {
#Override
protected void configureServlets() {
/* bind the REST resources */
bind(Test.class);
serve("/*").with(GuiceContainer.class);
}
});
}
}
GuiceConfigurationModule.java
public class GuiceConfigurationModule extends AbstractModule {
#Override
protected void configure() {
bind(ConfigurationManager.class).asEagerSingleton();
bind(ConnectionPool.class).asEagerSingleton();
}
}
ConfigurationManager
public class ConfigurationManager {
// Nothing important here, loading from config file
}
ConnectionPool (It's not working here)
public class ConnectionPool {
private static final Logger log = LoggerFactory.getLogger(ConnectionPool.class);
private ComboPooledDataSource pooledDataSource;
#Inject
private ConfigurationManager cManager;
public ConnectionPool() {
log.info("Initializing c3p0 coonection pool");
pooledDataSource = new ComboPooledDataSource();
try {
//Null pointer exception here, cManager is null
pooledDataSource.setDriverClass(cManager.getJdbcDriverClassName());
pooledDataSource.setJdbcUrl(cManager.getJdbcUrl());
pooledDataSource.setUser(cManager.getDatabaseUsername());
pooledDataSource.setPassword(cManager.getDatabasePassword());
} catch (PropertyVetoException e) {
log.error("Exception during c3p0 initalisation.", e);
//TODO obrada izuzetaka
}
}
}
Test.java (It's working here)
#Path("/test")
public class Test {
#Inject
ConfigurationManager cManager;
#GET
#Path("/{param}")
public Response getMsg(#PathParam("param") String msg){
// cManager is not null, it's injected as it should be
String output = cManager.getDatabaseHostName();
return Response.status(200).entity(output).build();
}
}
Field ConfigurationManager cManager will be injected when object construction is completed. That's why you are getting NPE in constructor and everything is fine in Test.java class.
Consider replacing field injection with constructor injection.
Just try this code
public class ConnectionPool {
#Inject
public ConnectionPool(ConfigurationManager cManager) {
...
}
}