I am trying to run Jersey 2.1 REST service on JBoss 7.1 AS. I am getting the NoSuchMethodError: javax.ws.rs.core.Application.getProperties error during deployment:
ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/RESTService]] (MSC service thread 1-9) StandardWrapper.Throwable: java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:271) [jersey-server-2.1.jar:]
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:283) [jersey-container-servlet-core-2.1.jar:]
In pom.xml I have:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.1</version>
</dependency>
And in the web.xml:
<servlet>
<servlet-name>RESTService</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.gatekeeper.restservice.RESTApplication</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Previously I tried with Jersey 1.17.1 and it worked (after disabling resteasy scan and jaxrs extension/subsystem in JBoss). So far I've found one similar post (but with Tomcat) where the conslusion was that the wrong javax.ws.rs.core.Application is being bound at runtime, and further that the bound class is an "old" (JAX-RS 1.1) version.
Any help how to resolve this? I'm .net guy and I'm totally blind in java :)
Thanks
Bartek
I know this thread is not that fresh, but still, I only hit this problem yesterday and nothing seems to work.
My scenario is very similar: Jersey 2.23.1 REST App (JAX-RS 2.x) already running on tomcat and need to run on JBoss 7.1.1 (built-in JAX-RS 1.1).
Turn off Restease package scanning in your web.xml:
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.providers</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.resources</param-name>
<param-value>false</param-value>
</context-param>
Remove all tags with "jaxrs" from standalone.xml. Otherwise you will still face LinkageError because JBoss keeps 1.1 spec on.
Create yourApp.war!WEB-INF\jboss-deployment-structure.xml just like is pointed out here: https://docs.jboss.org/author/display/AS7/Class+Loading+in+AS7#ClassLoadinginAS7-JBossDeploymentStructureFile
This way, not only:
java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;
Disapears, but also, JAXB works fine (No ClassNotFoundException for javax.xml.bind.JAXBException once module javax.xml.bind.api is also activated).
Obs1: The original question is mixing jersey 1.x with jersey 2.x. There is no PojoMappingFeature in jersey 2.x and base package is org.glassfish.jersey. Take a look at https://jersey.java.net/documentation/latest/migration.html#mig-1-x-json
Obs2: I have also tried other approaches like extending ResourceConfig and scanning packages from there or registering classes directly. Nothing worked like the proper documentation in item 3. So kept my servlet untouched:
<servlet>
<servlet-name>WebNize REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>br.com.webnize.rest.service</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WebNize REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
I hope it helps others!
In short, significant structural changes have been made between 1.17 and 2.2 of the Jersey implementation. You need to:
1) Extend your application class from "org.glassfish.jersey.server.ResourceConfig"
2) Add the packages line within the application class constructor, like so:
public class MyApplication extends ResourceConfig {
public MyApplication() {
packages("com.mysite.MyApplication");
}
}
3) Within web.xml, you'll need to update a number of places. See below:
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.mysite.MyApplication</param-value>
</init-param>
4) Deploy and have fun.
Additionally, it seems that the practice of using wildcards within the java source is deprecated.
Not this)
#Path("/v1/status/*")
But this)
#Path("/v1/status")
An improvement, IMHO.
Related
I have to migrate a rest web application to Java 11. I know, it is not trivial and I found out there many related posts. But, somehow none of them is my case.
The application is in use and runs in a Apache Tomcat 8.5.75 with Openjdk 1.8.0.222-2.b10.
Now, just simple deploying the application into an Apache Tomcat 9.0.58 with Eclipse Adoptium 11.0.14.1, the servlets are throwing java.lang.IllegalArgumentExceptions:
10-Jun-2022 08:13:45.840 SEVERE [main] org.apache.catalina.core.ApplicationContext.log Servlet.init() for servlet [RestOxServlet] threw exception
java.lang.IllegalArgumentException
at jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:170)
...
Such a servlet looks like this:
<servlet>
<servlet-name>RestOxServlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>
mx.ox;
mx.common.ox
</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>
mx.ox.rest.Log4jServiceLoggingFilter;
mx.common.ox.servicelogging.filter.ServiceLoggerServerFilter
</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>
my.ox.rest.Log4jServiceLoggingFilter;
mx.common.ox.servicelogging.filter.ServiceLoggerServerFilter
</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.feature.logging.DisableEntitylogging</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.feature.XmlRootElementProcessing</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
The use libraries are:
com.sun.jersey.contribs:jersey-apache-client4:jar:1.19.4:compile
com.sun.jersey.contribs:jersey-apache-client:jar:1.19.4:compile
com.sun.jersey.contribs:jersey-multipart:jar:1.19.4:compile
com.sun.jersey.contribs:jersey-spring:jar:1.19.4:test
com.sun.jersey:jersey-client:jar:1.19.4:compile
com.sun.jersey:jersey-core:jar:1.19.4:compile
com.sun.jersey:jersey-server:jar:1.19.4:compile
com.sun.jersey:jersey-servlet:jar:1.19.4:compile
It is know that with Java 11 many of those classes/packages vanished from JDK. Who has already solved this kind of problem? Is there an equivalency table with all dependencies for Java 11?
SK
How to declare multiple packages in the web.xml for the RESTEasy jax-rs provider?
If I have:
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Restful Web Application</display-name>
<!-- this need same with resteasy servlet url-pattern -->
<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>part1.MessageApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
It's working.
But If I have :
And then change the declaration of the web.xml (which is based on this way, which may have already worked in Jersey)
<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>part1.MessageApplication;part2.MessageApplication2</param-value>
</init-param>
</servlet>
Whenever I try to access a #Path-mapped-class in package "part2" it will throw :
java.lang.RuntimeException: java.lang.ClassNotFoundException: part1.MessageApplication;part2.MessageApplication2 from
Note that I'm aware that I've changed the #Path-mapped-class with different url path like #Path("controller2").
How do I configure it properly in the web.xml?
Not sure if I clearly understand your problem. The link you provided in your question is about specifying multiple packages. But looks like you are dealing with two Application subclasses. It's a different matter.
In this situation, you should register two HttpServletDispatcher mapped to different URI patterns, as following:
<!-- Application 1 (part1.MessageApplication) mapped to /rest/app1/* -->
<servlet>
<servlet-name>resteasy-application1</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>part1.MessageApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-application1</servlet-name>
<url-pattern>/rest/app1/*</url-pattern>
</servlet-mapping>
<!-- Application 2 (part2.MessageApplication2) mapped to /rest/app2/* -->
<servlet>
<servlet-name>resteasy-application2</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>part2.MessageApplication2</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-application2</servlet-name>
<url-pattern>/rest/app2/*</url-pattern>
</servlet-mapping>
Each Application subclass is mapped to a path that serves as the base URI for the resource URIs provided by #Path annotation.
You could have multiple Application subclasses when you support multiple versions of the API, for example. For simple applications, it's very likely you don't need that.
You may not need a web.xml
As per your comment, you are using WildFly 8. It's Servlet 3.0 compatible so you don't even need a web.xml deployment descriptor for simple applications. Most of the configurations, such as registering servlets, filters and listeners can be done via annotations.
In case you are not providing a web.xml deployment descriptor for your Maven-based web application project, you need to configure your maven-war-plugin to ignore the missing web.xml file by setting the failOnMissingWebXml configuration property to false in your project pom.xml file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
Since the version 3.0.0 of the maven-war-plugin, the default value for failOnMissingWebXml has been changed from true to false. You can use the most recent version and ommit that configuration property.
If, for some reason, you want to keep the web.xml, it can be as simple as:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
</web-app>
A few words on the Application class
Regarding JAX-RS, annotate your Application subclass with #ApplicationPath specifying the base URI for your resource classes:
#ApplicationPath("api")
public SampleApplication extends Application {
}
In the example above, the JAX-RS runtime will scan the classpath for JAX-RS components and will register them automatically.
If you want to manually register your resources and providers (preventing the JAX-RS runtime from registering the components automatically), override the getClasses() and/or the getSingletons() methods:
#ApplicationPath("api")
public SampleApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new HashSet<>();
resources.add(MyResource.class);
resources.add(MyOtherResource.class);
return resources;
}
}
For more details on the Application class, this answer can provide you some insights.
Managing your dependencies
It's worthwhile to mention that RESTEasy 3.x is shipped with WildFly. If you will use only the JAX-RS API the following dependency will give you all you need:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
If you need to use any type from the RESTEasy API, add the RESTEasy 3.x dependencies with the provided scope. It tells Maven that the container will provide that dependency, hence they won't be shipped with your application. Failing to provide the right scope may cause some weird errors and bad headaches. For more details on scopes, check the dependency scope documentation.
After deploying my war file, Weblogic changes the url-pattern, which i've defined in web.xml for my Jersey RESTful. As you can see, I want to access my service under /rest/* but weblogic changes it to /resources/*. Where can I configure it for WebLogic?
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>ch.ni.service</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
p.s it works with tomcat, as desired
I ran into a similar problem moving an application from Glassfish 3 to Weblogic 12.2.1. I finally caved in and followed the Jersey tutorial here.
I used the web.xml that was generated in the example to fix the code I was working on.
Short answer is I had to change the web.xml servlet definition to look like:
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>your.package.with.JAXRS.resources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webservices/*</url-pattern>
</servlet-mapping>
I also took the dependencies from the POM in the example and used them in my POM.
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.24</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.24</version>
</dependency>
Hope it helps.
I'm having hard time to get RESTeasy working with my existing application. I can hit my end points (AdminService). My problem is everytime I make a GET request (over browser) I hit twice on my service so it leads to duplicate results. I tried with POST using a java client still the problem is there. Following you can find my technology list.
Spring security 3.x
Spring 2.5
RestEasy 2.3.5.Final
==Part of my 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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>au.com.esriau.dekho.application.ApplicationLoader</listener-class>
</listener>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
</listener-class>
</listener>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>rest</param-value>
</context-param>
<context-param>
<param-name>resteasy.resources</param-name>
<param-value>com.admin.AdminService
</param-value>
</context-param>
I'd appreciate your solution or idea to trouble shoot this.
cheers
Don't bother reading this. This was due to my custom implementation of AbstractAuthenticationProcessingFilter in spring-security. I was basically making unnecessary call to the super class with super.doFilter(request, response, chain). This was done right after I execute my custom filters. Getting rid of super.doFilter resolved the issue for me.
Fyi, I am using Maven and Eclipse 3.6
Is it possible to deploy "felix" to JBoss (4.2.3) - such that I could access the Gogo shell from my Eclipse console?
If so - what kind of "descriptor" should I use? I've only ever encountered the "servlet" type deployments, with web.xml file:
<servlet>
<servlet-name>JerseyTest</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.resources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>