Integrating Jersey and Spring: Take 2

Marc previously described how to integrate Spring with Jersey 0.4 for the instantiation of root resources. This was an great first step but it fell short in a couple of areas:

  • there was some initialization code that could not be performed at initialization stage;
  • it was necessary to annotate (or specify the default provider for) all resources with a Spring specific life-cycle annotation, thus it was not possible to write 'vanilla' resources for use with Spring; and
  • this was only applicable to root resource classes. Jersey has other components, such as instances of MessageBodyReader/Writer, and it would be useful if those components could also be Spring-enabled.

I have spent this week unifing the instantiation of components (in addition to removing the requirement of META-INF/services for registration, it is all dynamic like for root resource classes). Instantiation of any component managed in Jersey is deferred to a ComponentProvider. By default Jersey provides a basic implementation but it is possible to  provide an application-specific implementation for say Spring. Jersey will then adapt that implementation so that Spring-registered and non-Spring-registered components can be instantiated.

(All code referenced below only works with the latest build of Jersey.)

I am still pondering the best way to declare an application-specific ComponentProvider but for now i am experimenting specifically with a Spring aware Servlet. Jersey ships with a servlet that can be extended to configure the WebApplication, which makes it very easy to extend for Spring support. Below is the code for the SpringServlet:

public class SpringServlet extends ServletContainer {
   
    private static class SpringComponentProvider implements ComponentProvider {
        private ApplicationContext springContext;

        SpringComponentProvider(ApplicationContext springContext) {
            this.springContext = springContext;
        }
       
        private String getBeanName(Class c) {
            String names[] = springContext.getBeanNamesForType(c);
            if (names.length == 0) {
                return null;
            } else if (names.length > 1) {
                throw new RuntimeException("Multiple configured beans for "
                        + c.getName());
            }
            return names[0];           
        }
       
        public Object getInstance(Scope scope, Class c)
                throws InstantiationException, IllegalAccessException {           
            String beanName = getBeanName(c);
            if (beanName == null) return null;
           
            if (scope == Scope.WebApplication &&
                    springContext.isSingleton(beanName)) {
                return springContext.getBean(beanName, c);
            } else if (scope == Scope.ApplicationDefined &&
                    springContext.isPrototype(beanName) &&
                    !springContext.isSingleton(beanName)) {
                return springContext.getBean(beanName, c);
            } else {
                return null;
            }
        }

        public Object getInstance(Scope scope, Constructor contructor,
                Object[] parameters)
                throws InstantiationException, IllegalArgumentException,
                IllegalAccessException, InvocationTargetException {
            return null;
        }

        public void inject(Object instance) {
        }       
    };
   
    @Override
    protected void initiate(ResourceConfig rc, WebApplication wa) {
        ApplicationContext springContext = WebApplicationContextUtils.
                getRequiredWebApplicationContext(getServletContext());
       
        wa.initiate(rc, new SpringComponentProvider(springContext));
    }       
}

Notice that SpringServlet extends ServletContainer and the initiate method is overridden. This method creates an ApplicationContext and then initiates the WebApplication by passing in an instance of the static inner class SpringComponentProvider. This class implements ComponentProvider and the getInstance method will attempt to obtain a Spring bean that is present and matches the requested scope, if so then the bean instance is returned otherwise null is returned. (Note that the getInstance method with a Constructor type parameter is not implemented, this is because we have not determined how to support constructors with Spring beans).

The SpringServlet can be used in a web.xml as follows:

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
    <listener>
        <description>Spring listener that initializes the ApplicationContext in ServletContext</description>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>   
    <servlet>
        <servlet-name>Jersey Spring</servlet-name>
        <servlet-class>test.spring.SpringServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Spring</servlet-name>
        <url-pattern>/\*</url-pattern>
    </servlet-mapping>
</web-app>

Then i can create two root resource classes. The first, SingletonResource, uses the Jersey supplied singleton life-cycle:

@Path("singleton")
@Singleton
public class SingletonResource {
   
    private String name;
   
    private int uses = 0;
   
    private synchronized int getCount() {
        return ++uses;
    }
   
    public SingletonResource() {
        name = "unset";
    }

    public String getName() {
        return name;
    }
   
    public void setName(String name) {
        this.name = name;
    }
   
    @GET
    @ProduceMime("text/plain")
    public String getDescription() {
        return "Name: " + getName() + ", Uses: " + Integer.toString(getCount());
    }
}

and the second, PerRequestResource, uses the per-request life-cycle:

@Path("request")
public class PerRequestResource {
   
    private String name;
   
    private int uses = 0;
   
    private synchronized int getCount() {
        return ++uses;
    }
   
    public PerRequestResource() {
        name = "unset";
    }

    public String getName() {
        return name;
    }
   
    public void setName(String name) {
        this.name = name;
    }
   
    @GET
    @ProduceMime("text/plain")
    public String getDescription() {
        return "Name: " + getName() + ", Uses: " + Integer.toString(getCount());
    }
}

The root resources are almost identical except that the former is annotated with @Singleton, but they should return different output (as shown later).

Then i can create the Spring applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans">
    <bean id="bean1" scope="singleton" class="test.spring.SingletonResource">
        <property name="name" value="Mr. Singleton Bean"/>
    </bean>
    <bean id="bean2" scope="prototype" class="test.spring.PerRequestResource">
        <property name="name" value="Mr. PerRequest Bean"/>
    </bean>
</beans>

Where the root resource classes are registered (with the appropriate scope) and a property is specified for each.

Then i can deploy and test using curl (the '>' character is my shell prompt): 

> curl http://localhost:8080/SpringResourceWebApp/singleton ; echo
Name: Mr. Singleton Bean, Uses: 1
> curl http://localhost:8080/SpringResourceWebApp/request ; echo
Name: Mr. PerRequest Bean, Uses: 1
>
> curl http://localhost:8080/SpringResourceWebApp/singleton ; echo
Name: Mr. Singleton Bean, Uses: 2
> curl http://localhost:8080/SpringResourceWebApp/request ; echo
Name: Mr. PerRequest Bean, Uses: 1
>
> curl http://localhost:8080/SpringResourceWebApp/singleton ; echo
Name: Mr. Singleton Bean, Uses: 3
> curl http://localhost:8080/SpringResourceWebApp/request ; echo
Name: Mr. PerRequest Bean, Uses: 1

Notice that the response to the URI containing the 'singleton' path segment returns the 'Mr. Singleton Bean' property as specified in the applicationContext.xml, and similarly the URI containing the 'request' path segment returns the 'Mr. PerRequest Bean' property. Also notice that the Uses value for the singleton-based URI increments for each request where as the one for the request-based URI does not. It works!

Having to edit  applicationContext.xml is something i would prefer to avoid and instead utilize some Spring specific annotations. The ComponentProvider interface could probably do with some tweaks to make things more efficient for per-request life-cycle. But in general it seems to work reasonably well and i am sure the same concepts for Spring integration would apply to Guice.

Comments:

Awesome! This is just what I have been waiting for. I was using a work around for managing instances using a resource factory but this approach is much cleaner.

Posted by Aaron Anderson on February 01, 2008 at 09:52 AM CET #

Would it be possible to put the 0.6-SNAPSHOT version on a maven repository somewhere ? Or point me to it if it already exists. It would make it a lot easier to test this version. Thanks.

Posted by peter on February 03, 2008 at 06:25 AM CET #

Hi Peter,

We are currently only pushing stable early access releases to the java.net repo. The reason being is that we want to push just stable versions of the JSR expert group agreed JAX-RS API.

Version 0.6 is still under development. We have not fully implemented the JAX-RS 0.6 API (which was frozen last week) and i plan to make changes to some of the Jersey specific APIs. A stable version of 0.6 is due to be released on March 7th. 0.6 is currently only available from the latest download section of the Jersey project site. This package is updated every time a commit is performed.

Can you live with things like that until the 0.6 stable release?

Paul.

Posted by Paul Sandoz on February 04, 2008 at 10:25 AM CET #

Paul,

I understand your point. But wouldn't it be possible to have a separate snapshot repository. I don't know how hard or easy that would be for a public project. Users choosing that repository know what to expect :-)

Posted by peter on February 05, 2008 at 01:52 AM CET #

Hi Paul!

You closed the comments on the http://blogs.sun.com/sandoz/entry/javarebel_and_jersey, but I wanted to let you know that the OSS SDK is up here: http://code.google.com/p/zt-oss/. We also integrated both Google Guice and Apache Stripes to update the runtime model, some docs are up on the site.

Posted by Jevgeni Kabanov on February 05, 2008 at 02:13 AM CET #

Hi Peter,

I will ask for some advice on the Jersey users list as there are some maven experts lurking there. Then i will see what we can do. Perhaps we could always push the latest build out to a maven repo. Cannot promise anything just yet!

Paul.

Posted by Paul Sandoz on February 05, 2008 at 03:37 AM CET #

Hi Jevgeni,

Re: closing of comments. By default roller automatically closes the comments after 7 days. I have changed the config so it never closes them.

Re: the update. Looks like it should be reasonably easy to specify a specific JavaRebel aware WebApplication instance that implements ReloadListener. Veyr nice! I am a bit busy over the next couple of weeks but i hope i will have time to look into this before the 0.6 release on March 7th and at least get a prototype working.

BTW any interest in providing hooks for debugging with NetBeans?

Posted by Paul Sandoz on February 05, 2008 at 03:49 AM CET #

Re: NetBeans

I'm not sure if debugging with NetBeans is a problem, however both IntelliJ IDEA and Eclipse plugins are open source, so there shouldn't be need for any special hooks for NetBeans.

Posted by Jevgeni Kabanov on February 05, 2008 at 03:57 AM CET #

Hi Paul,

Would it be possible for you to list the dependency jars for you aproach to having jersey integrated with spring ?

Thanks,
Leo

Posted by leo de blaauw on February 08, 2008 at 01:48 AM CET #

Hi Leo,

The core jars for Jersey are required, as documented here [1]:

jersey/lib/asm-3.1.jar
jersey/lib/jersey.jar
jersey/lib/jsr311-api.jar

Then i included:
spring-framework-2.5.1/lib/jakarta-commons/commons-logging.jar
spring-framework-2.5.1/dist/spring.jar

Paul.

[1] https://jersey.dev.java.net/source/browse/\*checkout\*/jersey/trunk/jersey/docs/dependencies.html

Posted by Paul Sandoz on February 08, 2008 at 04:58 AM CET #

Paul,

In using your example I seem to have a problem not finding the @Singleton annotation on my classpath. I am using jersay 0.6 with all its libs on the classpath at this time ?

Regards,
Leo

Posted by leo de blaauw on February 08, 2008 at 05:01 AM CET #

Hi Leo,

What package name for @Singleton are you using?

Here are the import statements for the SingletonResource:

import com.sun.ws.rest.spi.resource.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.ProduceMime;

Note that the @Singleton annotation is part of the Jersey API (not currently part of the JAX-RS API).

Paul.

Posted by Paul Sandoz on February 08, 2008 at 05:09 AM CET #

Hi Paul,

I've tried your example, but in my current version of jersey (February 1st) the mechanism only works for the singleton.

More specifically, both in your examples and my own code, the only spring beans for which a ComponentProvider.getInstance(.. is invoked are those annotated with @Singleton and @Path

The @Path requirement is logical.

But I also have a very specific question. What if you would take the Bookmark example, but used @PersistenceContext the spring way (meaning you would not pass the Entitymanager from UsersResource to UserResource, but inject it) - how would you do that? It seems like a case that would be useful for many people.

Posted by peter on February 11, 2008 at 02:11 AM CET #

Hi Peter,

Did you declare the scope of 'bean2' to be 'prototype' in applicationContext.xml? Are you using the same version of Spring (2.5.1) ?

Re: the bookmark example. I agree. We have been discussing a number of options:

1) Return a class that gets instantiated.

2) Return an instance, where injection can happen on that instance. AFAIK Spring only supports injection on beans it is in control of although IIRC WebBeans will allow this behaviour.

3) Allow the injection of ComponentProvider on resources so that they can instantiate an instance using that interface.

Paul.

Posted by Paul Sandoz on February 11, 2008 at 02:36 AM CET #

Hey all,

Well, prototype is not really a good option in my view for most use-cases. Mostly I would like to to access service classes at a lower level to allow them to be accessed via a REST interface. Therefore I need those services to be Singletons really. In relation to that I really would like Spring to be in full controll of the lifecycle of those service classes and manage the instantians and destroy of them as well as any transactions and security involved.

Regards,
Leo

Posted by Leo de Blaauw on February 11, 2008 at 08:03 AM CET #

I have now a version where the injection works, but I have a new problem.

A resource class, class example.UserResource$$EnhancerByCGLIB$$42882142, does not have any resource method, sub-resource method, or sub-resource locator

Cglib causes the annotations to dissapear.

Do you think Jersey could look at the parentclass when looking for the correct GET/PUT/DELETE annotations ?

Posted by peter on February 11, 2008 at 08:36 AM CET #

Hi Leo,

It was not exactly clear to me what 'prototype' in Spring actually meant and under what scope instances were available. Plus it does not really gel well with the constructors that take parameters. So i am a bit uncomfortable with it.

By default the life-cycle in JAX-RS is per-request, but you can configure the Web application to have an init-param of:

com.sun.ws.rest.config.property.DefaultResourceProviderClass

whose value points to the @Singleton class (see JavaDoc of ResourceConfig). Then all resource classes will be Singleton by default.

Paul.

Posted by Paul Sandoz on February 11, 2008 at 08:46 AM CET #

Hi Paul,

Prototype pretty much means a freshly initialized bean on every getBean you make. Now I agree you want a JAX-RS life-cycle per request, but not for the underlying resources like services, daos and even dbconnections etc. I havent had the chance yet to try your suggestion but I will let you know if that works out. Pretty much I would just like to insert a spring managed bean into my (REST) webservice class for utilisation there.

Regards,
Leo

Posted by Leo de Blaauw on February 11, 2008 at 08:50 AM CET #

Hi Peter,

Can you send email to the Jersey users list:

users@jersey.dev.java.net

as there are others who may be able to help you as they have got hibernate working with Jersey.

Jersey does look at all public methods on the resource class and super classes. Maybe Cglib is encapsulating and not reproducing the annotations on methods?

Paul.

Posted by Paul Sandoz on February 11, 2008 at 08:53 AM CET #

Oh,

And at the point I am doing a getbean on the service class, all injection into that service class would have allready been fully completed and it would be ready to service any requests from the webservice class. Therefore constructor injection or setter injection doesnt really matter anymore.

Regards,
Leo

Posted by Leo de Blaauw on February 11, 2008 at 08:53 AM CET #

Oh,

One more ;-) Maybe its easier to discuss these things on an irc channel ? Is there a #jersey somewhere ?

Greetz
Leo

Posted by Leo de Blaauw on February 11, 2008 at 08:54 AM CET #

Hi Leo,

Thanks for the info on prototype. There is the jersey users list, no IRC unfortunately. This is the most comments i have ever had on a blog entry!

You should be able to achieve what you want using the Spring ComponentProvider as Jersey will defer instantiation and injection to Spring and will not interfere with the Spring injected stuff you have configured. It will inject additional stuff using @HttpContext. It does ask for instantiation of some web-application scoped components for reading/writing and JAXB support on initialization. Those can also be deferred to Spring for instantiation and injection, they are always singletons. Only the scope of root resource classes can be controlled by an annotation.

Paul.

Posted by Paul Sandoz on February 11, 2008 at 09:09 AM CET #

Paul I am using netbeans to develop the RESTful web services with spring support.. Following the directions given in your blog i made an appl.. but the wadl is not formed .. and on deployment wadl not found error is shown

Posted by Vineet on March 03, 2008 at 11:15 PM CET #

Hi Vineet,

Some questions:

What URI are you using to access the WADL?

Are you getting any exceptions printed out when you try to access the WADL?

Is JAXB in the class path?

Note that in the latest build i have removed GET support for getting the WADL of a resource. It is now only possible to use OPTIONS to obtain the WADL of a resource. The reason being is using GET caused a lot of interference with the application (and especially MVC stuff i am experimenting with) and GET with a WADL-based media type could not be consistently used (i may re-investigate this to see if there is a non-intrusive way).

Using GET for the <base URI>/application.wadl remains unchanged.

Also there is currently a bug in the latest build that inadvertently introduced a runtime dependency on the Jettison jars when created WADL. This will be fixed very soon.

Hope this helps,
Paul.

Posted by Paul Sandoz on March 04, 2008 at 04:15 AM CET #

I want 2 use Jersey in Netbeans 5.5.
What is the way to do it. I have tried creating a web application added the jersey api in the library and edited the web.xml file.. But still the wadl file is not being accessed by the browser .. what else should i be doing ..?

Posted by Debashis Jana on March 05, 2008 at 03:48 AM CET #

Hi Debashis,

There should not be any restriction in using NetBeans 5.5 for development using Jersey. The easiest thing to do is copy an existing example in the Jersey distribution (which depends on NetBeans 6 but you can copy the relevant source/config files into a 5.5 project).

Did you get a basic service running? (for example, copying HelloWorldWebApp example distributed with Jersey).

What version of Jersey are you using?

What URL are you using to obtain the WADL?

Note that we changed the WADL generation functionality in 0.5 (and i have further changed it for the up and coming 0.6 release, ready this Friday)

Thanks,
Paul.

Posted by Paul Sandoz on March 05, 2008 at 03:55 AM CET #

Hey Paul actually i cant access the resources either..
i was trying to get the wadl file from base url/application.wadl.. but it is not found...n yeah jaxB is in the class path and no exception are reported but a message in the browser only ..

Posted by Vineet on March 05, 2008 at 06:00 AM CET #

Would it be possible to do something similar with Jetty and Jersey like your example with Spring and Jersey?

Thanks

Posted by Jon on March 06, 2008 at 03:33 AM CET #

Vineet,

It is hard to track the conversation via the blog would it be possible to transfer things over to email:

users@jersey.dev.java.net

?

What is the message in the browser?

Have you tried doing:

curl -v <url>

if so what is the output?

Paul.

Posted by Paul Sandoz on March 06, 2008 at 05:12 AM CET #

Hi Jon,

It should be possible as Jetty is a Web container.

I am looking for volunteers to experiment with Jetty :-) as i would like to add in process Web container support using Jetty for servlet-based unit tests.

Paul.

Posted by Paul Sandoz on March 06, 2008 at 05:15 AM CET #

Hi,

very helpful posting, this should go into the documentation :)

Just one improvement could be made to support PerRequest scoped resources that have constructor arguments:
the getInstance(Scope, Constructor, Object[]) method (which returns null in your example) should be changed to return getInstance( scope, constructor.getDeclaringClass() ).

This seems to be a difference of the PerRequestProvider and SingletonProvider.

Cheers,
Martin

Posted by Martin Grotzke on March 06, 2008 at 12:44 PM CET #

[Trackback] Hi, my last post is nearly years ago (mhh, bad english?) and of course I wanted to write about this and that. But right now I had so much fun that I have to share this&#8230; Fun with&#8230; jersey, the reference implementation for the upcoming jsr311 ...

Posted by javakaffee on March 07, 2008 at 09:15 PM CET #

Do you have any plans to include the Spring integration code inside Jersey? Given how popular Spring is for IoC this would be a very good thing - plus having a little demo showing a web app using Spring for IoC with Jersey doing the JAX-RS goodness!

Posted by James Strachan on March 13, 2008 at 02:34 AM CET #

The formatting is probably gonna be lousy :) but here's an improved implementation of the SpringComopnentProvider - here http://rafb.net/p/esp72A36.html - or I've posted it here......

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import com.sun.ws.rest.spi.service.ComponentProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;

/\*\*
\* @version $Revision: 1.1 $
\*/
public class SpringComponentProvider implements ComponentProvider {
private static final transient Log LOG = LogFactory.getLog(SpringComponentProvider.class);
private final ConfigurableApplicationContext applicationContext;
private int autowireMode = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
private boolean dependencyCheck;

public SpringComponentProvider(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}

public <T> T getInstance(Scope scope, Class<T> type) throws InstantiationException, IllegalAccessException {
String name = getBeanName(type);
Object value;
if (name != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Found bean named: " + name);
}
value = applicationContext.getBean(name, type);
}
else {
LOG.debug("No bean name so using BeanFactory.createBean");
value = applicationContext.getBeanFactory().createBean(type, autowireMode, dependencyCheck);
}
return type.cast(value);
}

protected <T> String getBeanName(Class<T> type) {
String[] names = applicationContext.getBeanNamesForType(type);
String name = null;
if (names.length == 1) {
name = names[0];
}
return name;
}

public <T> T getInstance(Scope scope, Constructor<T> constructor, Object[] objects) throws InstantiationException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
return constructor.newInstance(objects);
}

public void inject(Object object) {
String beanName = getBeanName(object.getClass());
if (beanName != null) {
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
beanFactory.configureBean(object, beanName);
}
}

// Properties
//-------------------------------------------------------------------------
public int getAutowireMode() {
return autowireMode;
}

public void setAutowireMode(int autowireMode) {
this.autowireMode = autowireMode;
}

public boolean isDependencyCheck() {
return dependencyCheck;
}

public void setDependencyCheck(boolean dependencyCheck) {
this.dependencyCheck = dependencyCheck;
}
}

Posted by James Strachan on March 13, 2008 at 03:30 AM CET #

Hi James,

I would like very much to include Spring support plus an example with the Jersey distribution. The Spring and Guice integration with Jersey has been a very popular topic. It is a resource issue rather than anything technical (although my Spring knowledge is limited the feedback has been very helpful and instructive on how best to implement basic support) but we will strive to get something in for the 0.7 release on April 18th.

Thanks for the code update, very helpful. (BTW the link you sent returns a 404.)

Paul.

Posted by Paul Sandoz on March 18, 2008 at 03:53 AM CET #

Hi James,

is it correct, that with this SpringComponentProvider each component is created as a spring bean?

What are the consequences of these changes?

Thanx a lot,
cheers,
Martin

Posted by Martin Grotzke on March 18, 2008 at 01:19 PM CET #

Thanks for the post!
It works great on the server side but we ran into problem when we tried to access JSP resource, it showed 404 error. How should we configure web.xml?

Posted by CH L on April 16, 2008 at 08:21 PM CEST #

Hi CH L,

This is an area we need to improve.

The solution i currently use is to set the servlet-mapping URL parameter to be "/". In at least GF and Tomcat this makes the Web container check for JSP pages first, from my minimal investigations.... See the Bookstore example in the Jersey distribution for a web.xml and access to a JSP page.

I want to investigate transforming the Jersey servlet into a servlet filter as this might make it easier to integrate with existing JSP/HTML pages.

We are also working on improving the Spring integration. Martin Grotzke who has commented on this blog entry is working on it. The plan is to get this into the 0.8 release.

Hope this helps,
Paul.

Posted by Paul Sandoz on April 17, 2008 at 05:06 AM CEST #

Thanks for the quick response!
Servlet filter sounds like a good idea.

Posted by CH L on April 21, 2008 at 12:29 AM CEST #

Hi, Paul,
Nice stuff. Peter Liu has written an implementation of your example code using NB 6.1, and I'd like to blog it myself and cross-post it to NetBeans Zone, with a link back to here, if that's OK with you.

Posted by Jeff Rubinoff on May 18, 2008 at 10:51 AM CEST #

[Trackback] REST 0.7 is out and now includes support for the Spring framework. Peter Liu has written a nice example that uses NetBeans 6.1 to create a web application that contains a Spring-aware servlet, a singleton resource, and a request resource. His example i...

Posted by Are you being Web serviced? on May 18, 2008 at 12:02 PM CEST #

I have created a web application which contains a .jsp page and a singletone resource .whenever the .jsp page is requested it is giving the following error
Requested Url : /index.jsp
org.apache.jasper.JasperException: Unable to compile class for JSP:

An error occurred at line: 22 in the generated java file
The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory

Stacktrace:
at org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:92)
at org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:330)
at org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:423)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:308)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:286)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:273)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:566)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:390)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:654)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:445)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:292)
at org.iitkgp.erp.service.filter.DigitalSignatureFilter.doFilter(DigitalSignatureFilter.java:65)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:390)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
how to solve it??????
pls help?
i am using netbeans 6.0,jax-rs 0.6.0.2(jsr311) apache tomcat of netbeans 6.0.

Posted by Somesh Ghosh on May 26, 2008 at 05:59 AM CEST #

Hi Somesh,

It appears you might have a jar mis-match, namely if you get a "the method getJspApplicationContext(ServletContext) is undefined for the type JspFactory" does it imply that the method is missing?

I am not sure of the interaction with Jersey and the JSP pages. Can you send more information e.g. zip'ing up a complete example, and sending it to:

mailto:users@jersey.dev.java.net

Thanks,
Paul.

Posted by Paul Sandoz on May 26, 2008 at 06:54 AM CEST #

sir,
I have checked that abstract method getJspApplicationContext(.) is present in JspFactory, but the application could not find this method. I can't understand why it is happening.
pls help.
thanks

Posted by Somesh Ghosh on May 27, 2008 at 11:15 PM CEST #

Hi Somesh,

I really do not know what is going on either :-( To help me help you i need you to send me some source code and instructions so that i can compile, run and reproduce.

Paul.

Posted by Paul Sandoz on May 28, 2008 at 02:13 AM CEST #

I have the same problem that Somesh has.
I have NB 6.1 with integrated Tomcat 6.0.16.
My webservices work great but I cannot run a jsp. I get the error:
The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory

Now if I create a new web application without RESTful webservices, I have no problems.
One of the projects that gives me this error is the NetBeans bundled HelloWorld project.
Any ideas?

Posted by G F on May 30, 2008 at 01:54 PM CEST #

Hi Somesh, G F

The problem could be specific to the RESTful Web services support in NetBeans. I will discuss with the tooling team and get back to you.

Paul.

Posted by Paul Sandoz on June 03, 2008 at 05:04 AM CEST #

Sir,
I have an another problem.
I have created a RESTful application. Here i want a list of resources present in this application only using the name of the application . how can i get this?
Also, how can i get the physical application.wadl file?
from that file i can extract the resorces.
please give me some hints or clue?
thanking you,

Posted by Somesh Ghosh on June 09, 2008 at 09:27 AM CEST #

Somesh,

Can you please email your question to:

users@jersey.dev.java.net

As it is much easier to have a more relevant conversation. Plus others may be able to help you or benefit from the responses.

BTW on the NetBeans related issue: We found the problem, it was due to NB shipping a lower version of the JSP jar with the RESTful plugin. We are trying to the fix (remove the jar) into the 6.1 patch2 release that should be out by the end of June.

Thanks,
Paul.

Posted by Paul Sandoz on June 09, 2008 at 09:36 AM CEST #

Hi,

For testing I want to invoke this SpringServlet (using URLConnection), however it is not getting invoked, that is I cannot see corresponding URL's method getting executed. What care I should be taking (in terms of http method or type of input).
Also I have an html file as a welcome file in web.xml and it is also not getting displayed. Any idea??

Posted by tarap on August 07, 2008 at 04:53 AM CEST #

Hi Tarap,

Can you send an email to:

users@jersey.dev.java.net

describing your problem in more detail. If you can provide more information on your set up, preferably some example code and configuration files etc that would help myself and others to help you.

Thanks,
Paul.

Posted by Paul Sandoz on August 07, 2008 at 05:02 AM CEST #

Hi Paul,

Since JAXBContext objects are resource intensive, I want to create some JAXBContext objects for a particular scenario and save them in the data store which is maintained by JAXRS framework.

How can I access the JAXRS application store which holds the JAXBContext objects which are created in an application.

Posted by Thulasi on January 25, 2010 at 06:42 PM CET #

Hi Thulasi,

I think the best solution is for the application to declare to JAX-RS the JAXBContext to be used for a set of JAXB classes.

You can register an instance of ContextResolver<JAXBContext>.

For example:

@Provider
public class Foo implements ContextResolver<JAXBContext> {
private final JAXBContext jb = ...;

public JAXBContext getContext(Class<?> type) {
if (/type is part of context) {
return jb;
} else {
return null;
}
}
}

You register Foo (a provider class) as you would register any root resource classes.

Posted by Paul Sandoz on January 26, 2010 at 02:03 AM CET #

Paul,
Working with jersey 1.1.5 & json & gwt on the client.
When returning dates which have 0 milliseconds, the gwt parser crashes because the .000 milliseconds are dropped if a date has 0 millis.
Is there a way to specify the serialization/deserialization date format (we don't need the millis on the client)

Thanks

Tony

Posted by tony on June 01, 2010 at 12:55 PM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

sandoz

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today