Jboss 5, Jersey 2.4, Compressed .war file not working - rest

I am developing some RESTful webservices using the following technologies
* Java 1.7
* Jersey 2.4.1
* spring 3.2.1
* Jboss-5.1.0.GA
So far, I have used eclipse to build the war file, both an exploded version and a compressed version. I have copied the files one at a time to {jboss-home}/server/web/deploy and have started the server using the command line by running run.bat -c web. In both cases the server starts up without error and the log files are identical. (timestamps excluded)
When I deploy the exploded war file and then navigate to the url http://mydomain.com:8080/{app}/rest/application.wadl, jersey is correctly identifying the annotated resources and I can use them as expected.
jersey annotated
#Path("/v1/ping")
#Service("pingV1")
public class PingV1 extends BaseResource {
#Autowired
private PingBusiness pingBusiness;
#GET
#Produces(MediaType.APPLICATION_XML)
public PingVO getPing(
#Context UriInfo uriInfo,
#Context HttpServletRequest httpServletRequest){
...
PingVO pingVO = pingBusiness.doGet();
...
return pingVO;
}
}
application.wadl (dynamically generated)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
<doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 2.4.1 2013-11-08 12:08:47"/>
<grammars>
<include href="application.wadl/xsd0.xsd">
<doc xml:lang="en" title="Generated"/>
</include>
</grammars>
<resources base="http://mydomain.com:8080/{app}/rest/">
<resource path="/v1/ping">...</resource>
<resource path="/">...</resource>
<resource path="application.wadl">...</resource>
</resources>
</application>
However, when I deploy the compressed .war file and navigation to the same url http://mydomain.com:8080/{app}/rest/application.wadl, jersey it not finding the annotated resource and when I hit the expected urls jboss returns a 404 - NOT FOUND.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
<doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 2.4.1 2013-11-08 12:08:47"/>
<grammars/>
<resources base="http://mydomain.com:8080/{app}/rest/">
<resource path="application.wadl">...</resource>
</resources>
</application>
Lastly, I used winRAR to extract the contents of the compressed war file into a folder, then used Beyond Compare to do a folder comparison of the original exploded war to the contexts that were just extracted and they were IDENTICAL.
This leads me to believe that there is something unique about how jboss deploys exploded wars vs compressed war files, but I don't understand what that may be or why it behaves this way. Can anyone help or point me in a new direction?
While a simple response could be ok, well just deploy the exploded war file, I would like to understand why this happens and continue to use my existing build.xml which produces the compressed .war file.

You can try this:
public class MyApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(HelloWorldResource.class);
return s;
}
}
or other examples from the Jersey documentation if you want to use reflection to get the resources.
You may have a condition where the unpacking of the war is interfering with the jersey autoscan process and this should fix it.

<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.xyz.app.rest.MyApplication</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.xyz.app.rest</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>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
package com.xyz.app.rest;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class MyApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(MyDataResource.class);
return s;
}
}

Related

serving HTML/JSP in a restful webapp using jersey & java

I Can't seem to figure it out. tried to use annotations and web.xml to configure paths to webcontent but keep getting unknown resources.
Jersey main:
#ApplicationPath("/")
public class App extends PackagesResourceConfig {
public App() {
super("webapp.resources");
}
}
Jersey default path "/": (hello world works! index.html\jsp does not)
#Path("/")
#Produces(MediaType.TEXT_HTML)
public class RootResource
{
#GET
public String index(#Context HttpServletRequest request) {
return "hello world";
}
}
What I've tried:
multiple web.xml config
serving viewables (error cannot resolve template index.jsp)
what do you think can be a solution to serve pages like html or jsp?
is there a way to do it with jersey (no spring!) and viewable\templates?
to answer my question. futuretelematics's solution should work for most people. it is a known and valid solution. so WHY didn't work when i did it:
question 1:
after much fiddling around i discovered that once i changed the application root path from "/" to "/api" (or /???) suddenly everything started to play along. must be a jersey thing. i read somewhere that in order to make the "/" work you should map with filter in the web.xml. I would love to hear if anyone has done that successfully.
so right now it serves my initial page with JSP. that page i can manipulate with jsons in a rest fashion.
question 2:
making #viewable work was just a matter of creating the right folder structure path in WebContent (com/webapp/model/index(<-- jsp)). that's how the viewable page redirect works.
This should be easy; try the following:
The /WEB-INF/web.xml file:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
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>Your REST end Point</display-name>
<!-- /////////////////////// JERSEY (NO SPRING) ///////////////////////// -->
<servlet>
<servlet-name>MyRESTEndPoint</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<!- Package where jersey will scan for resources ->
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.mycompany</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyRESTEndPoint</servlet-name>
<url-pattern>/MyRESTEndPoint/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
AT package com.mycompany (look at at the web.xml) place the Application class:
package com.mycompany;
public class MyApp
extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(MyResource.class);
// ... add other resources
return s;
}
}
Create the resource like:
#Path("myResourcePath")
public class R01ERESTResourceForStructure {
#GET #Path("{myResourceId}")
#Produces(MediaType.APPLICATION_XML)
public Response load(#PathParam("myResourceId") final String id) {
....
}
}
Your urls should be: like /MyRESTEndPoint/myResourcePath/myResourceId
If you're using SPRING or GUICE the web.xml should be a bit different
Jersey provides support for JSP templates in jersey-mvc-jsp extension module
check out the official doc

Jersey REST Web Service, Tomcat, Eclipse and 404's

I've read through a number of posts, but just can't seem to solve my problem. You'll also see tons of posts very similar to this one, even the same tutorial. Even following them, I can't seem to get to the answer.
Essentially, I'm trying to follow the simple tutorial at: http://www.vogella.com/articles/REST/
I've made a few changes to make it compatible with Jersey 2.x
I'm using:
Eclipse
Tomcat 6 (Deployed/Run as within Eclipse)
jaxrs-ri-2.0
I've enabled the JAX-RS Facet in Eclipse
Everything builds fine
Tomcat starts fine within Eclipse
I can get to a static page content via:
http://localhost:8080/RestTEST2/index.html
However, when I try to access my service via:
http://localhost:8080/RestTEST2/jaxrs/hello
I receive a 404 with "message not found" and "The requested resource (Not Found) is not available."
Here is my web.xml which is located at /WebContent/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>TestREST2</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<description>JAX-RS Tools Generated - Do not modify</description>
<servlet-name>JAX-RS Servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>TestREST</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS Servlet</servlet-name>
<url-pattern>/jaxrs/*</url-pattern>
</servlet-mapping>
</web-app>
Here is my Java class:
package TestREST;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
// Plain old Java Object it does not extend as class or implements
// an interface
// The class registers its methods for the HTTP GET request using the #GET annotation.
// Using the #Produces annotation, it defines that it can deliver several MIME types,
// text, XML and HTML.
// The browser requests per default the HTML MIME type.
//Sets the path to base URL + /hello
#Path("/hello")
public class Hello {
// This method is called if TEXT_PLAIN is request
#GET
#Produces(MediaType.TEXT_PLAIN)
public String sayPlainTextHello() {
return "Hello Jersey";
}
// This method is called if XML is request
#GET
#Produces(MediaType.TEXT_XML)
public String sayXMLHello() {
return "<?xml version=\"1.0\"?>" + "<hello> Hello Jersey" + "</hello>";
}
// This method is called if HTML is request
#GET
#Produces(MediaType.TEXT_HTML)
public String sayHtmlHello() {
return "<html> " + "<title>" + "Hello Jersey" + "</title>"
+ "<body><h1>" + "Hello Jersey" + "</body></h1>" + "</html> ";
}
}
I also have a JAX-RS User Library configured and referenced that includes all the JAX-RS jars.
Thoughts on what would cause the web service to not be found?
Jersey 2.0 does not recognize init-param with name com.sun.jersey.config.property.packages (web.xml). Try to change it to jersey.config.server.provider.packages as described in ServerProperties.PROVIDER_PACKAGES.
UPDATE (2020): try this link for current apidocs ServerProperties.PROVIDER_PACKAGES:
Thanks a lot.. i've been fighting for it as well.
This combination worked for me:
Tomcat 7.0.55
Eclipse Luna
Java 1.6
Jersey 1.7
web.xml:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.trgr.cobalt.cmdb.jersey.resource;com.trgr.cobalt.cmdb.jersey.beans;com.trgr.cobalt.cmdb.elasticity</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
I would like to add one answer in this post.I was struggling with same problem for two days and couldn't find the solution.
I tried all the possible solutions provided here but later on I realized that server was giving error of
org.glassfish.jersey.servlet.ServletContainer ClassNotFoundException
This link answers gives the solution if somebody is stuck like me..
org.glassfish.jersey.servlet.ServletContainer ClassNotFoundException
Actually first answer given in this post suggest the solution which is for jersey 2.x bundle and if you are using jersey 1.x then it will keep on giving error.
Kindly refer to link given in answer for further reference
Simply by modifying the configuration of Apache Tomcat v7.0 while creating Dynamic Web Project, to include REST, I solved my problem. It is not enabled by default.
Recently I found myself stuck in this problem. I have got it resolved by following these two points as the solution:
By making the src/main/java as the source directory, and keeping the Project Structure as shown below:
Changing com.sun.jersey.config.property.packages to jersey.config.server.provider.packages in the web.xml

Injection of an EJB into a web java class under JBoss 7.1.1

I am trying to build a website using JBoss 7.1.1 and RESTeasy. I have managed to constructed and deploy and EAR with a both a WAR and an EJB-JAR contained within:
voyager-app.ear
META-INF/MANIFEST.MF
META-INF/application.xml
META-INF/jboss-app.xml
lib/voyager-lib.jar
voyager-adm.war
voyager-ejb.jar
voyager-web.war
So far things are very simple. voyager-adm.war & voyager-lib.jar are empty (just the manifest file) but I know that I'm going to have code for them shortly. There is just one Stateful EJB - HarbourMasterBean (with just a local interface) and a few Database Entity Beans in the EJB jar file:
voyager-ejb.jar
META-INF/MANIFEST.MF
META-INF/persistence.xml
com/nutrastat/voyager/db/HarbourMasterBean.class
com/nutrastat/voyager/db/HarbourMasterLocal.class
com/nutrastat/voyager/db/PortEntity.class
com/nutrastat/voyager/db/ShipEntity.class
As far as I can tell the EJBs deploy correctly because the database units are created and the log shows that the publication of some HarbourMaster references:
java:global/voyager-app/voyager-ejb/harbour-master!com.nutrastat.voyager.db.HarbourMasterLocal
java:app/voyager-ejb/harbour-master!com.nutrastat.voyager.db.HarbourMasterLocal
java:module/harbour-master!com.nutrastat.voyager.db.HarbourMasterLocal
java:global/voyager-app/voyager-ejb/harbour-master
java:app/voyager-ejb/harbour-master
java:module/harbour-master
The problem lies in getting the HarbourMaster EJB injected into my web bean. The reference to it is alway NULL no matter what I try.
voyager-web.war
META-INF/MANIFEST.MF
WEB-INF/web.xml
WEB-INF/classes/com/nutrastat/voyager/web/
WEB-INF/classes/com/nutrastat/voyager/web/Ships.class
WEB-INF/classes/com/nutrastat/voyager/web/VoyagerApplication.class
Ships.java:
#Path("fleet")
public class Ships {
protected transient final Logger log;
#EJB
private HarbourMasterLocal harbourMaster;
public Ships() {
log = LoggerFactory.getLogger(getClass());
}
#GET
#Path("ships")
#Produces({"text/plain"})
public String listShips() {
if (log.isDebugEnabled())
log.debug("Harbour master value: " + harbourMaster);
return "Harbour Master: " + harbourMaster;
}
}
<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>Voyager Web Application</display-name>
<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>
<init-param>
<param-name>
javax.ws.rs.Application
</param-name>
<param-value>
com.nutrastat.voyager.web.VoyagerApplication
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
I have been searching the web for an answer and read a number of places, both on StackOverflow and elsewhere that suggests is can be done, and that the problems lies with configuration. But they post only snippets and I'm never sure if I'm doing things correctly.
Many thanks for any help you can provide.
Dobbo
What happens if you do:
#Path("fleet")
#Singleton
public class Ships {

Implementing Rest Easy with Tomcat

I have a Dynamic Web Project with a set of jsp's and a custom controller servlet, that is working great. But, I also need to implement a rest easy exposed service on it, and that's why i changed the web. xml to contain rest easy servlet also. and the application class which invokes the rest easy resource. But, when i am adding changes to web.xml, it is hitting rest easy servlet, but throwing exception..
java.lang.ClassNotFoundException: org.scannotation.AnnotationDB$CrossReferenceException
Web.xml :
<servlet>
<display-name>ControllerServlet</display-name>
<servlet-name>ControllerServlet</servlet-name>
<servlet-class>com.example.ControllerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>CollRestApi</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.exampl.RestApiApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ControllerServlet</servlet-name>
<url-pattern>/ControllerServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>CollRestApi</servlet-name>
<url-pattern>/or/*</url-pattern>
</servlet-mapping>
Rest Api Application :
public class RestApiApplication extends Application{
private Set<Object> singletons = new HashSet();
private Set<Class<?>> empty = new HashSet();
public RestApiApplication() {
// ADD YOUR RESTFUL RESOURCES HERE
this.singletons.add(new CollRestApi());
}
public Set<Class<?>> getClasses()
{
return this.empty;
}
public Set<Object> getSingletons()
{
return this.singletons;
}}
And CollRestApi.. is having exposed services..
#Path("api")#Consumes({ "application/xml", "application/json" })#Produces({application/xml", "application/json" })public class CollRestApi {
/**
* #return
*/
#GET
#Path("ab")
public Response do() {
System.out.println("Inside the do Method.");
}}
Obviously, you need to add scannotation.jar to your classpath. RESTEasy 2.2.2.GA depends on scannotation-1.0.3 and javassist-3.12.1.GA.jar which you also need.
I just faced the same problem using maven and netbeans. The answer is to add the jboss maven repository to your pom.xml-file. Just adding <dependency>....</dependency>, e.g. by using netbeans maven browser, doesn't install the dependecies of resteasy.
<repositories>
<repository>
<id>jboss</id>
<url>http://repository.jboss.org/nexus/content/groups/public-jboss/</url>
</repository>
</repositories>
I had the same exception, and fixed it like this:
Is it possible you have the resteasy**.jar libraries in a different location (e.g. the tomcat lib dir) than other resteasy-supporting libs like scannotation-1.0.3.jar (e.g. in your war file WEB-INF/lib) ?
In such a configuration your resteasy classes will start in a different classloader which does not see the scannotation-1.0.3.jar classes.
=> Try putting all resteasy jar files in either one of the locations (preferably your .war file).

Jetty and GWT (Google Web Toolkit)

As I understand it, GWT uses an embedded Jetty server. Can
anyone please tell me where I can find the Jetty .xml configuration files
used by GWT? I have a webapp which makes uses of Jetty's
ContinuationFilter and ProxyServlet. The app works fine under GWT but
fails when run in a separate Jetty instance outside of GWT. If I can
replicate the GWT Jetty config then I think I'll be okay.
Edit for more info:
My webapp's web.xml reads as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<filter>
<filter-name>JettyContinuationFilter</filter-name>
<filter-class>org.eclipse.jetty.continuation.ContinuationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>JettyContinuationFilter</filter-name>
<url-pattern>/bugzilla/*</url-pattern>
</filter-mapping>
<!-- Servlets -->
<servlet>
<servlet-name>greetServlet</servlet-name>
<servlet-class>com.searchsystem.gwt.server.GreetingServiceImpl</servlet-class>
</servlet>
<servlet>
<servlet-name>jetty-proxy-servlet</servlet-name>
<servlet-class>org.eclipse.jetty.servlets.ProxyServlet$Transparent</servlet-class>
<init-param>
<param-name>ProxyTo</param-name>
<param-value>http://localhost/</param-value>
</init-param>
<init-param>
<param-name>Prefix</param-name>
<param-value>/</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>greetServlet</servlet-name>
<url-pattern>/dashboard/greet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jetty-proxy-servlet</servlet-name>
<url-pattern>/bugzilla/*</url-pattern>
</servlet-mapping>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>Dashboard.html</welcome-file>
</welcome-file-list>
</web-app>
and the link to my Bugzilla installation is in this form:
com.google.gwt.user.client.ui.Frame bugFrame = new Frame("/bugzilla/");
Running under Jetty 6.1.26, I get this output:
Request Attributes
Attribute: Value:
javax.servlet.forward.request_uri /bugzilla/
org.mortbay.jetty.error_page /jspsnoop/ERROR/404
javax.servlet.forward.servlet_path /bugzilla/
testFilter 1
javax.servlet.error.message NOT_FOUND
requestInitialized ''
javax.servlet.forward.context_path
javax.servlet.error.status_code 404
javax.servlet.error.servlet_name default
org.mortbay.jetty.newSessionId 47deq3eo5kblxfrvtc5rljrg
javax.servlet.error.request_uri /bugzi
lla/
there is no jetty.xml. GWT sets up the Server programmatically.
You can find the setup in
com.google.gwt.dev.shell.jetty.JettyLauncher
contained in the gwt-dev.jar
See: Serving a GWT Application with an Embedded Jetty Server by Brandon Tilley (code extract shown below). He seems to have achieved it quite seamlessly, a process which I will be confirming myself tomorrow.
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.WebAppContext;
public class EmbeddedGwt {
public static void main(String[] args) throws Throwable {
// Create an embedded Jetty server on port 8080
Server server = new Server(8080);
// Create a handler for processing our GWT app
WebAppContext handler = new WebAppContext();
handler.setContextPath("/");
handler.setWar("./apps/GwtApplication.war");
// If your app isn't packaged into a WAR, you can do this instead
WebAppContext altHandler = new WebAppContext();
altHandler.setResourceBase("./apps/GwtApplication");
altHandler.setDescriptor("./apps/GwtApplication/WEB-INF/web.xml");
altHandler.setContextPath("/");
altHandler.setParentLoaderPriority(true);
// Add it to the server
server.setHandler(handler);
// Other misc. options
server.setThreadPool(new QueuedThreadPool(20));
// And start it up
server.start();
server.join();
}
}