GWT Guice/Gin on the server side problem - java

Hi guys with my question. A GWT project, as i have read Gin i usable only on the client side than Guice is usable on the server side. Here is my question.
Let first post some example code.
Server side.
public class WebchargeServiceImpl extends RemoteServiceServlet implements WebchargeService
{
#Inject
private Injector injector;
#Inject
private ExecuteOperations executeOperations;
.....
executeOperations.do(); ....
Here is the injected class ExecuteOperations
#Singleton
public class ExecuteOperations
{
.........
}
Also i have servlet module class
public class SampleWebGuiceServletConfig extends GuiceServletContextListener
{
#Override
protected Injector getInjector()
{
return Guice.createInjector(Stage.DEVELOPMENT, new SampleWebModule());
}
} // class
.....
public class SampleWebModule extends ServletModule
{
#Override
protected void configureServlets()
{
bind(WebchargeServiceImpl.class); //is it correct to bind a class like that?
} // class
web.xml
<servlet>
<servlet-name>.......WebchargeService</servlet-name>
<servlet-class>.....WebchargeServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>.........WebchargeService</servlet-name>
<url-pattern>/Webcharge/WebchargeService</url-pattern>
</servlet-mapping>
<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>......SampleWebGuiceServletConfig</listener-class>
</listener>
</web-app>
I'm missing something because i get null every time, this code works ok in servlet/jsp env but here...
Advice place.
Thanks.

You have to map your WebchargeServiceImpl servlet in your SampleWebModule, not in your web.xml; otherwise it'll be constructed by your servlet container and not by Guice, so it won't be "injected".

How do your servlets get instantiated? Did you install the Guice Servlet Filter?

Related

Spring security ApplicationListener doesn't get called for AuthenticationSuccessEvent

In my security application, Spring security ApplicationListener doesn't get called for AuthenticationSuccessEvent
#Component
public class LoginListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {
#Override
public void onApplicationEvent(InteractiveAuthenticationSuccessEvent event)
{
log.info("Login success");
}
}
What should I do?
I am using xml based mvc configuration and I was initializing my security like this:
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(SecurityConfig.class);
}
}
I solved above mentioned problem by:
Remove java based initialization and initialize it by adding filter springSecurityFilterChain in web.xml.
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Also, I was getting bean wiring exception whenever I was trying to #Autowire any bean in my SecurityConfig class. That problem also solved.

cannot be cast to javax.ws.rs.core.Application in resteasy and EJB 3.0

I am getting exception com.sai.peps.ejb.frequentexceeding.FrequentExceedingBean cannot be cast to cannot be cast to javax.ws.rs.core.Application
I am using EJB 3.0 and jboss 5.1 & resteasy
Please suggested to me, where is my mistake.
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>resteasy.resources</param-name>
<param-value>com.sai.peps.ejb.frequentexceeding.MyRestApplication</param-value>
</context-param>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest/</param-value>
</context-param>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.sai.peps.ejb.frequentexceeding.MyRestApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Edited:
package com.sai.peps.ejb.frequentexceeding;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath("/rest")
public class MyRestApplication extends Application {
private Set<Object> resourceObjects = new HashSet<Object>();
private Set<Class<?>> resourceClasses = new HashSet<Class<?>>();
public MyRestApplication() {
resourceClasses.add(FrequentExceedingBean.class);
}
#Override
public Set<Class<?>> getClasses() {
return resourceClasses;
}
#Override
public Set<Object> getSingletons() {
return resourceObjects;
}
}
i have added this code.. Still not working
If your class com.sai.peps.ejb.frequentexceeding.FrequentExceedingBean should be the Aplication class as it is configured, it must extend javax.ws.rs.core.Application because the servlet container will instantiate an object of this class and then cast ist to javax.ws.rs.core.Application to be able to call it's getClasses() and getSingletons() method.
Update
Alas JBoss 5.1 has not yet Servlet 3.0., so you cannot confugre it without the web.xml.
Please check the accepted answer of this question for the needed entries in the web.xml file. The configuration is different from yours in respect to where the classnames are. I myself haven't used web.xml configuration for quite a time anymore, so I am not so firm there.
your web.xml seems a little bit messy.
The question is: why should you provide your own implementation fo Application class?
If you have
resteasy.scan = true
you don't need anything else (exept for proper annotations on your Resource and Providers classes to publish your resources).
if you have
resteasy.resources
valued with a list of resources
you can omit the resteasy.scan parameter and explicitly provide a list of resources to be published (in this case you put com.sai.peps.ejb.frequentexceeding.MyRestApplication and it's wrong, probably you should have put com.sai.peps.ejb.frequentexceeding.FrequentExceedingBean)
You may override Application class to move configuration out of web.xml and still have a strict control on the list of resources to be published with custom logic. Are you sure this is your need? If this is the case you should skip above configurations.
In any case choose one of the three methods

How do I configure my entity-filtering scope for security annotations in the web.xml?

Reading the jersey doc : https://jersey.java.net/documentation/latest/entity-filtering.html I was able to activate the SecurityEntityFilteringFeature by adding it to my web.xml along with other activated features.
So my web.xml's features part looks like that :
...
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
org.glassfish.jersey.server.gae.GaeFeature;
org.glassfish.jersey.server.mvc.jsp.JspMvcFeature;
org.glassfish.jersey.media.multipart.MultiPartFeature;
org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature;
org.glassfish.jersey.message.filtering.SecurityEntityFilteringFeature;
</param-value>
</init-param>
...
The annotations #PermitAll (which changes nothing) and #DenyAll (which always remove entity from json) work great.
The question is : to use the annotation #RolesAllowed I also need to register the roles in the entity-filtering scope as said in the documentation
EntityFilteringFeature.ENTITY_FILTERING_SCOPE - "jersey.config.entityFiltering.scope"
Defines one or more annotations that should be used as entity-filtering scope when reading/writing an entity.
But I can only configure it through my web.xml and I have nowhere to do the following :
new ResourceConfig()
// Set entity-filtering scope via configuration.
.property(EntityFilteringFeature.ENTITY_FILTERING_SCOPE, new Annotation[] {SecurityAnnotations.rolesAllowed("manager")})
// Register the SecurityEntityFilteringFeature.
.register(SecurityEntityFilteringFeature.class)
// Further configuration of ResourceConfig.
.register( ... );
Any guess ?
You can use a ResourceConfig and a web.xml together. It is not "either one or the other". For example
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.foo.JerseyConfig</param-value>
</init-param>
</servlet>
package org.foo;
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(...);
property(...);
}
}
Both the web.xml and the ResourceConfig registrations/configuration/properties, etc will be used. You can see some other deployment options, here.
If you really must stay away from the ResourceConfig (not sure why it would be such a problem), you can always create a Feature.
#Provider
public class MyFilteringFeature implements Feature {
#Override
public boolean configure(FeatureContext context) {
context.property(...);
context.register(...);
return true;
}
}
Then just register the feature (unless you are scanning packages, then it should be picked up with the #Provider annotation).

Share class instance between servlets

I have a web.xml that defines a Jersey Servlet of class org.glassfish.jersey.servlet.ServletContainer, that is then configured with my own application class that extends ResourceConfig using:
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.mypackage.AppResourceConfig</param-value>
</init-param>
In my AppResourceConfig class I am constructing and registering Metric's MetricRegistry and HealthCheckRegistry instances.
Now I want to add a Metric's Health Check servlet like what is described at https://dropwizard.github.io/metrics/3.1.0/manual/servlets/ - That is, create the Metric's servlets and listeners to provide instances of the metrics registries to the servlet, such as:
public class MyHealthCheckServletContextListener extends HealthCheckServlet.ContextListener {
public static final HealthCheckRegistry HEALTH_CHECK_REGISTRY = new HealthCheckRegistry();
#Override
protected HealthCheckRegistry getHealthCheckRegistry() {
return HEALTH_CHECK_REGISTRY;
}
}
and (in web.xml)
<listener>
<listener-class>com.example.MyHealthCheckServletContextListener</listener-class>
</listener>
But taking this route would mean I have two versions of each. I know that the registries are declared as public static so I can just access them directly, but I'd prefer not to do it that way.
Is there a way to inject these directly into my own servlet AppResourceConfig class?

How to serve JSPs using Guice 3.0?

I'm trying to serve a JSP from Guice. I don't find any basic examples on how to do this!
My setup :
web.xml
<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>org.example.Bootstrap</listener-class>
</listener>
org.example.Bootstrap (something like...)
public class Bootstrap extends GuiceServletContextListener
{
#Override
protected Injector getInjector()
{
return Guice.createInjector(new org.example.BootstrapModule());
}
}
org.example.BootstrapModule (something like...)
public class BootstrapModule extends ServletModule
{
#Override
protected void configureServlets()
{
// serve .JSPs
bind(org.apache.jasper.servlet.JspServlet.class).in(Scopes.SINGLETON);
serveRegex("/.*\\.jsp").with(org.apache.jasper.servlet.JspServlet.class);
// serve my controllers
bind(MainServlet.class).in(Scopes.SINGLETON);
serveRegex("/.*").with(MainServlet.class);
}
}
In MainServlet, I do something like :
request.getRequestDispatcher("test.jsp").include(request, response);
or
request.getRequestDispatcher("test.jsp").forward(request, response);
or
request.getRequestDispatcher("/test.jsp").include(request, response);
or
request.getRequestDispatcher("/test.jsp").forward(request, response);
My test.jsp is in webapp/test.jsp (I use Maven).
It doesn't work! I always end up with errors like :
SEVERE: PWC6117: File XXX not found
It seems the informations Guice passes to org.apache.jasper.servlet.JspServlet are not the ones required for the JSPs to work.
What am I missing? Do I even have to specify org.apache.jasper.servlet.JspServlet manually? What is required to correctly serve JSPs from Guice?
It seems this is a known bug.
As a workaround, some say you can compile the TRUNK of Guice. I also found that setting
request.setAttribute(org.apache.jasper.Constants.JSP_FILE, "/test.jsp");
before the forwarding also works.
But I have to run more tests to see what I'll use until Guice is fixed in a public release.
You need to override Bootstrap#getModule() to return a new BootstrapModule().
#Override
protected Module getModule() {
return new BootstrapModule();
}

Categories