Restful site broke after upgrading resteasy-jaxrs to the lastest version - maven

I'm going through this tutorial example on RestEasy:
http://www.mkyong.com/webservices/jax-rs/resteasy-hello-world-example/
I downloaded their code and made modification so that I can deploy it to tomcat 7 and java 1.7.
If I leave the pom.xml as specified by the site,
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>2.2.1.GA</version>
</dependency>
then everything appears to be fine and can be accessed through:
http://localhost:8080/RESTfulExample/rest/message/hello
However, if I were to increase the version level to 3.0.8.Final or "RELEASE",
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.8.Final</version>
</dependency>
then I can't access it via the above URL. Instead, I get this message in my localhost_access_log.txt
127.0.0.1 - - [19/Aug/2014:16:02:55 -0700] "GET /RESTfulExample/rest/message/hello HTTP/1.1" 404 -
Question: Does anyone know how I can get the pom.xml to work if I really want to use RESTeasy 3.0.8.Final? I'm new to Rest.
Thanks in advance.

As the documentation describes you can initialize RESTeasy in a standalone Servlet 3.0 compliant container by adding this dependency:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-servlet-initializer</artifactId>
<version>3.0.8.Final</version>
</dependency>
You should also update the web.xml with the correct Servlet version. Most of the old configuration stuff can be removed so you end up with:
<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">
<display-name>Restful Web Application</display-name>
</web-app>
Last thing to do is tell RESTeasy on which path you want to map your application by adding javax.ws.rs.ApplicationPath to the MessageApplication class:
#ApplicationPath("/rest")
public class MessageApplication extends Application {
...
}

Related

How do I fix HTTP Status 404 - Not Found on Intellij IDEA?

I've started my first job 2 months ago and it's been awhile since I've dealt with Spring. I'm trying to run Tomcat server, and display "/home" but I'm getting 404 on it. When I hover at my "home", IntelliJ IDEA is showing home.html . Error
HTTP Status 404 – Not Found
Type Status Report
Message The requested resource [/home] is not available
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
Apache Tomcat/9.0.65
HTTP error
Code folders screenshot
Tomcat config
Tomcat deployment config
I've googled about it but it's doesn't fix it. Here is my code.
File HomeController.java
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class HomeController {
#RequestMapping("/home")
public String landingPage() {
return ("home");
}
}
File home.html
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Landing page</h1>
</body>
</html>
File pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>demo</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
I also tried to run my older projects that works but now it doesn't.
Thank you in advance!
try to use ModelAndView:
#RequestMapping("/")
public ModelAndView index () {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("home");
return modelAndView;
}
You are using Spring Boot, which has an embedded Tomcat server. I believe you have a standalone Tomcat running on port 8080 on your machine, preventing Spring Boot from using its own embedded Tomcat.
Stop the standalone Tomcat and start the Spring Boot application again.
Everything looks good. Spring boot doesn't require you to do any tomcat configuration.
The configuration you have should be the problem. Re create the project without the Tom Cat config and deployment config.
Check out this video: https://www.youtube.com/watch?v=HYGnVeCs0Yg&t=4235s
As previous answers mentioned before, you're using Spring Boot, which has its embedded Tomcat server under the hood. It's the default behavior, but you may configure your Spring Boot project to use Netty or Undertow servers, please check more details here — Embedded Web Servers
So since you already have the Tomcat server, there is no need to configure it in your IDE. Also, worth mentioning that running a project from your IDE is not the best idea. Especially, when you're describing your steps for reproducing the issue to someone else. Instead, you may run your Spring Boot project from the command line using the such command:
mvn spring-boot:run
By default, it'll start your application on the 8080 port and you will be able to access your homepage at this URL: localhost:8080/home
For more details on running your Spring Boot application, you may check this document — Running your application
To run the Spring Boot project from your IntelliJ IDEA, you need to open the DemoApplication class (in your case), which has the main method. And on the left, there should be a play button for running your project. You can also configure it in the 'Edit configurations' menu by selecting the 'Spring Boot' item under the 'Add new configuration' menu.
Updated:
I'm using that you're using macOS. To identify the process running on the 8080 port, which prevents you from starting your Spring Boot application, you may use such command:
sudo lsof -i :8080
This is the example output of this command from my machine, which has the Docker container running on the 8080 port:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
com.docke 3134 golovnya 174u IPv6 0xcaf3b5f3fb45111 0t0 TCP *:http-alt (LISTEN)
Here we're interested in PID, which stands for the process identifier. It's a unique id of the running application. In my case, the PID of the process running on the 8080 port is 3134. Knowing this, we may kill this process by the following command:
kill -9 <PID>
In my case it will look like this:
kill -9 3134
That's all.
P.S. If it looks a bit complicated to your or you experience some issues, reloading your machine is always not a bad idea.

spring boot application deployment on weblogic throws 404 error

I have done below configurations and tried almost all solutions found but nothing helped. When i am deploying spring boot app in war package. no error got logged in weblogic log but the application throwing 404 error.
web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:root-context.xml</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>dev</param-value>
</context-param>
<context-param>
<param-name>spring.liveBeansView.mbeanDomain</param-name>
<param-value>dev</param-value>
</context-param>
weblogic.xml
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wls="http://www.bea.com/ns/weblogic/90"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
<wls:weblogic-version>12.1.2.0.0</wls:weblogic-version>
<wls:context-root>/services/userModule/</wls:context-root>
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>com.fasterxml</wls:package-name>
<wls:package-name>org.slf4j</wls:package-name>
<wls:package-name>org.springframework.*</wls:package-name>
</wls:prefer-application-packages>
</wls:container-descriptor>
</wls:weblogic-web-app>
application.properties
spring.profiles.default=default
spring.profiles.active=default
spring.liveBeansView.mbeanDomain=default
cms.config.monitor.dir=/server/location/application/artifacts
application.messages.file.name=application-messages
application.config.file.name=application-config
root-context.xml
it contains application specific configurations.
ApplicationBegin.java
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class})
public class ApplicationBegin extends SpringBootServletInitializer implements WebApplicationInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ApplicationBegin.class);
}
public static void main(String[] args){
SpringApplication.run(ApplicationBegin.class, args);
}
Cannot exclude tomcat server from pom.xml as it is failing the compilation. is there a way to set tomcat as provided while using spring boot starter web?
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<!-- THIS WILL BE EXCLUDE ONLY FOR WEBLOGIC DEPLOYMENT -->
<!-- <exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion> -->
</exclusions>
</dependency>
The problem is the application runs fine with embedded tomcat but it is not working even not throwing any error when deploying on weblogic. Where should i look?
Can you try class loading as the parent last? So Spring boot will use it's own container libraries.
After trying the solutions i found from different people , it couldn't solve my issue and somehow i have solved it now. all the similar issues i have seen on this topic and the soultions, i finally understood no answer was actually a solution because in most of the cases the issue happens because of wrong configuration that weblogic dosen't understand. the worst part being it doesn't even throw error. In my case other than application.properties file and a root-context.xml, i explicitly specified web.xml file in /WEB-INF location and defined context-config location there. As soon as i removed the web.xml and refactored/filtered the project dependencies from top to bottom , it resolved the issue.
and also then i realized many handy solutions on the web for this issue wouldn't even be required if your configuration is correct. for an example, configuring a jpavendor won't require if you use spring boot jpa starter correctly.
so.. if you ever face this kind of deployment issue on weblogic , you may follow below steps -
Only deploy a bareminimum part of application and make it workable
on weblogic
then add your critical dependencies / configurations and deploy them one by one on weblogic and check if it is working
you should always run your boot application to other local server first for resolving major configuration issues ..tomcat is
good.
I had the same problem, but I finally managed to solve it.
The problem was the version of web.xml descriptor. If you put the web.xml file in your project with <web-app version="2.5">, even though your Weblogic supports servlet 3.0, the spring controllers would throw 404.
That also explains the behavior of your app - what's why it started working when you removed the web.xml file.

JSF annotations don't work with Spring-boot

I had been tried to use info from Spring Boot and JSF/Primefaces/Richfaces, but for me it doesn't work.
I use Java 8, maven, Spring-boot and JSF with PrimeFaces.
I would like to have executable jar and run my application via main method or from command line java -jar myApp.jar.
The problem - JSF-annotations (#ManagedBean, #ManagedProperty) are ignored.
Pom file:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>7.0.54</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>7.0.54</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>7.0.54</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>5.0</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.2.7</version>
</dependency>
...
</dependencies>
I also have tried to add/remove javax.el-api/javax.el/jstl - the same result. For bean initialization I have added section to faces-config.xml
When I change spring-boot-starter-web to spring-boot-starter and have spring-web (according to solution from mentioned post from Herick) I got
java.io.FileNotFoundException: class path resource
[org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.class]
cannot be opened because it does not exist
My config class:
#Configuration
#EnableAutoConfiguration//(exclude = {WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class})
#ComponentScan("hello")
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class);
}
#Bean
public FacesServlet facesServlet() {
return new FacesServlet();
}
#Bean
public ServletRegistrationBean facesServletRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(facesServlet(), "*.xhtml");
registration.setName("facesServlet");
return registration;
}
#Bean
public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() {
return new ServletListenerRegistrationBean<ConfigureListener>(new ConfigureListener());
}
}
With (exclude = {WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class}) web.xml configuration doesn't work.
In mentioned post was:
#Bean
public ListenerRegistationBean jsfConfigureListener() {
return new ListenerRegistrationBean(new ConfigureListener());
}
ListenerRegistationBean is absent in my spring-boot and I have used ServletListenerRegistrationBean instead.
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Test</display-name>
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<error-page>
<location>/error.xhtml</location>
</error-page>
</web-app>
And faces-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
<managed-bean>
<managed-bean-name>managedBeann</managed-bean-name>
<managed-bean-class>hello.ManagedBeann</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
Because nonworking annotations is used.
By the way PrimeFaces is working.
My purpose is force JSF-annotation to work, because in real project without them it is impossible.
Disclaimer
I am answering this based on what I think you were trying to acheive even though my answer does not match the question title.
You said "My purpose is force JSF-annotation to work, because in real project without them it is impossible." I'm guessing you mean "impossible" because putting managed beans in the faces-config.xml is cumbersome. So to this end I am going to not use the faces-config.xml to manage beans.
I'm going to show you an alternative that uses Spring annotations which is very non-cumbersome and I feel accomplishes your original goal.
Answer
Example --
https://github.com/Zergleb/Spring-Boot-JSF-Example
I looked over your question the other day and decided to try and make this work and I put my results on github (Link above). This example should allow you to write a JSF application using Spring annotations instead of JSF annotations for example you'll say
#Component
#Scope("view")
//The example above contains an implementation of the View Scope in Spring.
instead of
#ManagedBean
#ViewScope
and you'll then be able to use Spring for all of your dependency injection.
I used gradle instead of maven so this means your dependencies are in the build.gradle instead of the pom.xml I had to add these in order to make everything work. Those should be easy enough to translate to a pom.xml I imagine.
compile group: 'javax.el', name: 'el-api', version: '1.0'
compile group: 'com.sun.el', name: 'el-ri', version: '1.0'
compile group: "javax.servlet.jsp" name: "jsp-api" version: "2.1"
My web.xml only has one servlet now and I removed the servlet-mapping and all of the other attributes of the web.xml
(I'm still working on how to remove this web.xml altogether check the example for any updates on whether I figured it out or not)
<web-app ... same as before>
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
</web-app>
faces-config.xml now has no managed beans
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd" version="2.2">
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
</faces-config>
I do not have this right now but we might want to consider having an empty in the web.xml I haven't researched this a ton but one of the spring-project examples on github contains this code
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-traditional/src/main/webapp/WEB-INF/web.xml
<!-- Disables Servlet Container welcome file handling. Needed for compatibility with Servlet 3.0 and Tomcat 7.0 -->
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>
I hope that answers your question. If I left something out try and reference the example code.
Example
https://github.com/Zergleb/Spring-Boot-JSF-Example
Runs a spring boot application that should both run Spring MVC and JSF in one application sharing a common context.(I included this in the answer because you referenced this link in your question Spring Boot and JSF/Primefaces/Richfaces which says that mixing Spring MVC and JSF is impossible but I have working in my example code.

Zest 1.1.0 cannot integrate with ZK 6.5.2

I am using ZK framework version 6.5.2 for my application. And now I want to integrate RESTful to it by using Zest. The problem is, the latest version of Zest is 1.1.0, and it depends on zcommon-5.0.0. So this dependency (zcommon-5.0.0) is duplicated and I excluded it from my POM file, like this:
<dependency>
<groupId>org.zkoss.zest</groupId>
<artifactId>zest</artifactId>
<version>1.1.0</version>
<exclusions>
<exclusion>
<groupId>org.zkoss.common</groupId>
<artifactId>zcommon</artifactId>
</exclusion>
<exclusion>
<groupId>org.zkoss.common</groupId>
<artifactId>zweb</artifactId>
</exclusion>
</exclusions>
</dependency>
As a result zest now depends on zcommon-6.5.2. When I start my app, an error occured:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to org.zkoss.xel.taglib.FunctionDefinition
at org.zkoss.xel.taglib.Taglibs.getFunctionMapper(Taglibs.java:150)
at org.zkoss.xel.taglib.Taglibs.getFunctionMapper(Taglibs.java:109)
at org.zkoss.zest.sys.impl.ParserImpl.parse(ParserImpl.java:97)
at org.zkoss.zest.sys.impl.ParserImpl.parse(ParserImpl.java:54)
at org.zkoss.zest.sys.ZestManager.loadConfiguration(ZestManager.java:98)
at org.zkoss.zest.sys.ZestManager.init(ZestManager.java:70)
at org.zkoss.zest.sys.ZestFilter.init(ZestFilter.java:74)
Here is my web.xml:
<filter>
<filter-name>zest</filter-name>
<filter-class>org.zkoss.zest.sys.ZestFilter</filter-class>
<!-- specifies the class name of the ZEST manager to handle actions Default: org.zkoss.zest.sys.ZestManager -->
<init-param>
<param-name>manager-class</param-name>
<param-value>org.zkoss.zest.sys.ZestManager</param-value>
</init-param>
<!-- specifies the class name of the parser used to parse the configuration file (WEB-INF/zest.xml). Default: org.zkoss.zest.sys.impl.ParserImpl -->
<init-param>
<param-name>parser-class</param-name>
<param-value>org.zkoss.zest.sys.impl.ParserImpl</param-value>
</init-param>
</filter>
And here is rest definition in zest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<zest>
<xel-method prefix="c" name="toMethodName"
class="com.myapp.view.RestAction"
signature="java.lang.String toMethodName(java.lang.String)"/>
<action path="/rest" method="${c:toMethodName(request.method)}"
class="com.myapp.view.RestAction">
<result>/WEB-INF/index.zul</result>
</action>
</zest>
I have compared the source code of these 2 files Taglibs.java in version 5.0.0 and 6.5.2 of zcommon and realized that they have so many differences. I think that the reason caused above problems (the initialization process has changed from 5.0.5 to 6.5.2). Could you please help me solve this problem so that I can integrate zest to my ZK application? Thank you so much.
Zest 1.1 is not compatible with ZK 6.5.2. You have to upgrade to Zest 2.0:
http://mavensync.zkoss.org/maven2/org/zkoss/zest/zest/2.0.0.FL.20130205/

How do I migrate from Jersey 1.0 to Jersey 2.0?

I'm trying to upgrade to Jersey 2.0 and I'm having a lot of trouble because the groupIds and artifactIds of Jersey have completely changed and I can't find a migration plan in the Jersey docs.
Here's what my pom.xml used to look like, and this compiled fine:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.17</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server-linking</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.17.1</version>
</dependency>
What should these be changed to? This unrelated StackOverflow question was somewhat helpful, but I'm having trouble finding things like where the #Ref annotation moved to.
Update
It seems that #Ref no longer exists or at least it's not mentioned in the documentation anymore. Now you use a UriBuilder.
I found a very helpful section in the documentation that answers my maven issues.
The HTTPBasicAuthFilter has been renamed to HttpBasicAuthFilter. Notice the capitalization.
Client client = Client.create(); has become Client client = ClientBuilder.newClient();
This:
String json = client
.resource(getBaseUrl() + url)
.accept(MediaType.APPLICATION_JSON_TYPE)
.get(String.class);
has become
String json = client
.target(getBaseUrl())
.path(url)
.request(MediaType.APPLICATION_JSON_TYPE)
.get(String.class);
You don't.
Jersey 2.0 is missing a lot of functionality from Jersey 1.0. Contrary to what the committers will tell you, some things are plain impossible to implement right now (e.g. Guice, Spring integration). Things appear to work on the surface, but once you dig in deeper you will find a lot of features are still broken.
Many of the 1.x plugins do not exist in 2.x, mainly because of the aforementioned breakage.
In light of this, I suggest a holding off on Jersey 2.x for the foreseeable future. Hopefully the committers will clean this up in the coming year.
It is pain in the neck I have to say.
We are currently knee deep into migrating relatively large 3+ years old client-server project and boy do I want to bite my neck off.
Hopefully we are at the end of the struggle...
While there is a migration guide indeed it is not comprehensive by any means.
UniformInterfaceException (and others) is no more.
Instead it is replaced by WebApplication exception and successors. There is not a word about that in the migration guide and this is very very important.
JSON support
The migration guide says:
JSON Support has undergone certain changes in Jersey 2.x. The most
visible difference for the developer is in the initialization and
configuration.
In Jersey 1.x, the JAXB/JSON Support was implemented as a set of
MessageBodyReaders and MessageWriters in the jersey-json module.
Internally, there were several implementations of JSON to Object
mapping ranging from Jersey's own custom solution to third party
providers, such as Jackson or Jettison. The configuration of the JSON
support was centralized in the JSONConfiguration and JSONJAXBContext
classes.
Great. What if you have chosen the "Jersey's own custom solution" (which we did for whatever reason)? There is no alternative to that in jersey 2. I tried to produce the same JSON format using Jettison, Jackson and Moxy providers. I did not succeed. For reference, my unanswered question here: Jersey 2 JSON Jettison unwrapping root element
See the 1.x to 2.0 migration guide in the Jersey docs. (2019 link to 1.x to 2.0 migration guide)
It looks like #InjectLink is the replacement for #Ref.
From that link, I was able to drop this into my pom.xml:
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-declarative-linking</artifactId>
<version>2.6</version>
</dependency>
and then I took an existing #Ref and was able to drop in replace with #InjectLink.
public Long id; // This id is referenced below in the link
#InjectLink(resource = FavoriteResource.class, method = "updateFavorites", bindings = {
#Binding(name = "listId", value = "${instance.id}")
})
public URI linkURI;
It looks like some of the JavaDocs from #Ref are in #InjectLink even, which would be further confirmation that it's the replacement:
/**
* ...
* #Ref(resource=SomeResource.class)
* #Ref(resource=SomeResource.class, bindings={
* #Binding(name="id" value="${instance.id}"}
* )
*/
EDIT:
Tricky stuff. I needed one more piece to make this work for me. In web.xml,
I now have:
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.mycompany.root</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>com.mycompany.root.web.filter.AuditResourceFilterFactory;com.mycompany.root.web.filter.OtherAuditResourceFilterFactory</param-value>
</init-param>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.mycompany.root.web.resource.config.CustomResourceConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
and finally, CustomResourceConfig.java looks like this
import org.glassfish.jersey.linking.DeclarativeLinkingFeature;
import org.glassfish.jersey.server.ResourceConfig;
public class CustomResourceConfig extends ResourceConfig {
public CustomResourceConfig() {
packages("org.glassfish.jersey.examples.linking");
register(DeclarativeLinkingFeature.class);
}
}
You can follow following steps for migration from Jersey 1 to Jersey 2 :
Add following dependencies in POM file :
Jersey 2.23.2 dependencies
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.23.2</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-entity-filtering</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.bundles.repackaged</groupId>
<artifactId>jersey-guava</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.23.2</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.5.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.jvnet</groupId>
<artifactId>mimepull</artifactId>
<version>1.6</version>
</dependency>
Make Following entry in Web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" 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">
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.jsg.resource.initializer.RestResourceInitializer</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping> '
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/myAppName</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
Write following code in RestResourceIntializer
package com.jsg.resource.initializer;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class RestResourceInitializer extends Application {
/**
* Gets the classes.
*
* #return the classes
*/
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
// Resources
classes.add(org.glassfish.jersey.jackson.JacksonFeature.class);
classes.add(org.glassfish.jersey.server.spring.scope.RequestContextFilter.class);
classes.add(org.glassfish.jersey.media.multipart.MultiPartFeature.class);
//Rest classes within Application.
classes.add(com.jsg.rest.AbcRestService.class);
classes.add(com.jsg.rest.CdeRestService.class);
return classes;
}
}
Now if you will deploy code with above changes on websphere,you will get following exception :
Caused by: java.lang.NoSuchMethodError: javax/ws/rs/core/Application.getProperties()Ljava/util/Map; at org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:287) at org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:311)
Reason for above exception is that,Websphere supports JAX-RS 1 implementation,however we are deploying Jersey 2 code which is Jax-rs 2 implementation.
Steps for resolving above exception:
So basically what we have to do is to force WebSphere to pick our Jersey 2 jars instead of default Jax-rs 1.We need to follow following steps for that
1) Disable in built JAX-RS by setting following JVM property to true
com.ibm.websphere.jaxrs.server.DisableIBMJAXRSEngine=true
This property can be set through admin console of WebSphere by going to Servers->All Server -> ->Server Infrastructure -> Java and Process Management ->Process Deifinition ->Additional Properties-> Java Virtual Machine ->Additional Properties-> Custom Properties
2) Create Isolated Shared Library having the Jersey 2 Jars and Spring 4 Jars
Isolated shared library can be created through admin Console of Websphere by going to Environment-> Shared Libraries ->New
n the classpath box,we need to enter path of the folder on the server,where we have placed all Jersey 2 and Spring 4 Jars
/var/was/server2/jerseyLib1/spring-context-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-core-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-beans-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-aop-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-web-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-expression-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-bridge-2.5.0-b05.jar
/var/was/server2/jerseyLib1/hk2-locator-2.5.0-b05.jar
/var/was/server2/jerseyLib1/hk2-api-2.5.0-b05.jar
/var/was/server2/jerseyLib1/hk2-utils-2.5.0-b05.jar
/var/was/server2/jerseyLib/javax.inject-2.5.0-b05.jar
/var/was/server2/jerseyLib1/javax.annotation-api-1.2-b03.jar
/var/was/server2/jerseyLib1/javax.ws.rs-api-2.0.1.jar
/var/was/server2/jerseyLib1/jersey-client-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-spring3-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-container-servlet-core-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-server-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-common-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-guava-2.23.2.jar
Also in class loading section ,select "use an isolated class loader for this shared library"
and then finally click on Apply and Ok and we are done with creation of isolated shared library.
Bind this isolated shared library with your application war file as follows in admin Console
a) Application -> All Applications -> Click on your application name
b) Go to References -> Shared Library References -> Reference Shared Libraries ->select your application war(Not ear) and click ok.
c) Select the library that we created in Step 2 in "Available" combo box on left side and put it on right side in "Selected" combo box and click ok.
With this we have associated the isolated shared library with application war file.
Restart Server and application should be up and running.

Resources