I am trying swagger for the first time with Jersey and Maven, and I am wondering if I am going down the right path. I have jersey, maven, and swagger working on my local computer. Soon, I want to deploy it to different environments and include swagger-ui.
If I configure my web.xml file to <param-value>http://localhost:8080/api</param-value> then I see that swagger works on my local computer. But will I need to change this address every time I want to deploy my code to different environments (for example going from a Dev environment, to QA environment, to Production environment), and if so how would I go about doing that or is it not possible/not what swagger is meant for?
I want to incorporate swagger-ui with my project. I see online suggestions of downloading the file manually from git and placing it in my project. But what I am wondering is if there is a maven dependency that I can use instead so that I can use maven to get the necessary code to use swagger-ui and configure it to work with jersey. If so what is the dependency and how do I use it to deploy the code through multiple environments?
Please give guidance and links to tutorials if possible seeing as I am new to this technology. Also if I am way off in my thought process of using jersey/swagger/swagger-ui/maven without manually downloading code from git and being able to deploy the code through multiple environments please let me know so I can look for another way to use REST in my application.
Thank you for your help.
pom.xml:
<repositories>
<repository>
<id>maven2-repository.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2/</url>
<layout>default</layout>
</repository>
</repositories>
<properties>
<jersey2.version>2.19</jersey2.version>
<jaxrs.version>2.0.1</jaxrs.version>
</properties>
<!-- Dependencies -->
<dependencies>
<!-- JAX-RS -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>${jaxrs.version}</version>
</dependency>
<!-- Jersey 2.19 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey2.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey2.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey2.version}</version>
</dependency>
<!-- Servlet Library -->
<!-- http://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring dependencies -->
<!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jersey2-jaxrs</artifactId>
<version>1.5.0</version>
</dependency>
</dependencies>
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_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>HelloWorldSpring</display-name>
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
io.swagger.jaxrs.listing,
com.jer.rest
</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>
<servlet>
<servlet-name>Jersey2Config</servlet-name>
<servlet-class>io.swagger.jersey.config.JerseyJaxrsConfig</servlet-class>
<init-param>
<param-name>api.version</param-name>
<param-value>1.0.0</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>http://localhost:8080/HealthTracker/rest</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- Other XML Configuration -->
<!-- Load by Spring ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml</param-value>
</context-param>
<!-- Spring ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
Check out the link https://github.com/swagger-api/swagger-samples/tree/2.0/java
It has excellent examples on how to configure Swagger 3.0 in your project (see java-jersey2-webxml example). For earlier versions check the branches
As far as the ui is concerned, you can download required files or you can just add the below dependency in pom.xml.
<dependency>
<groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId>
<version>3.6.1</version>
</dependency>
It will download necessary ui files. You can copy the downloaded index.html in your project and edit the url.
Here's what I think would answer your questions:
To be able to configure swagger as per different environments, then these are the steps you can follow:
i) Create a Bootstrap class to configure swagger bean (ref: https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-Jersey-2.X-Project-Setup-1.5 and Setting the Api Version with Swagger UI)
ii) Set the values in the above bean using values from a properties file, which you can easily configure outside your code in any environment.
Swagger dist consists of html/css/image/js files. It cannot be added as a Maven jar dependency.
Hope this helps!
Here a solution with java doclets (no swagger annotations are required). Use the maven-javadoc-plugin and configure the swagger-doclet as an alternate doclet. With maven profiles it is possible to manage different environments:
<profile>
<id>dev</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>generate-service-docs</id>
<phase>generate-resources</phase>
<configuration>
<doclet>com.carma.swagger.doclet.ServiceDoclet</doclet>
<docletArtifact>
<groupId>com.carma</groupId>
<artifactId>swagger-doclet</artifactId>
<version>1.0.3</version>
</docletArtifact>
<reportOutputDirectory>${project.build.outputDirectory}</reportOutputDirectory>
<useStandardDocletOptions>false</useStandardDocletOptions>
<additionalparam>-apiVersion 1 -docBasePath
https://example.com/apidocs -apiBasePath
https://example.com/api -swaggerUiPath
../../../src/main/resources/swagger-ui/
</additionalparam>
</configuration>
<goals>
<goal>javadoc</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
I put the swagger resources directly into my project. So it was easy to customize the css and html.
Or, if you do not want to put swagger into your repository, you could use the frotend-maven-plugin to manage your js/css dependencies (like: swagger-ui) with bower.
I deliver swagger as static resources from the embedded server directly (in my case I used grizzly) :
String apiDocs = Env.getApiDocs();
server.getServerConfiguration().addHttpHandler(
new CLStaticHttpHandler(GrizzlyStarter.class.getClassLoader(), apiDocs), apiDocs);
I was faced with the same problem and created a library that if included into a Jersey project will add swagger 3.0 UI. Please take a look code and blog post The idea is that all swagger UI static content is packaged withing the library and extracted at runtime. In addition, library will take care of creating web context for swagger UI and adjust reference to the openapi.json file. You will need to add 2 properties and this code to your project:
SwaggerContext.addSwaggerServlet(tomcat, context,
ConfigBuilder.builder(ConfigType.TYPE_SAFE)
.build()
.getConfig("swagger"),
EmailApplication.class);
and properties:
swagger.package="com.itzap"
swagger.apiBaseUrl="http://{application url}"
If all other configuration is left at defaults swagger UI can be accessed over this URL:
http://{application base URL}/api/v1/swagger
Related
I've tried many different ways to make the resteasy client work for me, but I'm stuck on an error.
java.lang.LinkageError: Failed to link org/jboss/resteasy/client/jaxrs/internal/ClientConfiguration
Here is the method I'm using as a client
public void createIssue() {
issue = new Issue();
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target("api-being-posted-to");
Response response = target.request().header("Authorization: ", "Basic Foo")
.post(Entity.entity(issueJson, "application/json"));
}
I can POST and GET with the same data this is using, and I've tried making a client work with different data and posting to different places and always get the same error. Here's my pom:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.foo.bar</groupId>
<artifactId>foo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>example</name>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.1.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<version>3.0.8.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.1.0.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
</plugin>
</plugins>
</build>
and here's my 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_3_0.xsd"
id="WebApp_ID" version="3.0">
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<listener>
<listener-class>
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
</listener-class>
</listener>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
</servlet>
I'm using JBoss EAP 6.4 if that helps.
As far as I can tell the provided version of resteasy in JBoss EAP 6.4 is 3.0.21.Final and not 3.1.0.Final but you might have modified that (see https://developer.jboss.org/thread/262213 for reference).
You use different versions and different scopes for your resteasy libraries (3.0.8.Final for jaxrs-api) but that might still be ok.
I would always recommend to use the Resteasy Proxy Framework. It might be a bit more code to write but makes things easier and clearer in total:
Define an Interface:
public interface IssueIF
{
#POST
#Path("/issue")
#Produces("text/plain")
Issue postIssue(Issue i);
}
Use it:
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target("http://example.com/base/uri");
SimpleClient simple = target.proxy(IssueIF.class);
Issue issue = new Issue();
client.postIssue(issue);
I did not compile this code, it is mostly copy/pasted from the docs but it should be close to what you need.
Edit:
From the docs:
Subclasses of LinkageError indicate that a class has some dependency
on another class; however, the latter class has incompatibly changed
after the compilation of the former class.
This suggest that you have a problem with different library versions you use for compilation and on runtime so see above at no 1.
Especially if you use different scopes it is essential that the versions are the same for compilation and runtime! So try to find out which versions your JBoss supplies and only use these versions. Also find out which of your referenced libraries are supplied and mark all of them with scope provided.
Following is my pom.xml
<project xmlns="Page on apache.org" xmlns:xsi="Page on w3.org"
xsi:schemaLocation="Welcome to Apache Maven/POM/4.0.0 Page on apache.org">
<modelVersion>4.0.0</modelVersion>
<groupId>com.MyStartUp.www</groupId>
<artifactId>MyStartUp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>MyStartUp Maven Webapp</name>
<url>Welcome to Apache Maven</url>
<properties>
<spring.version>4.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.6.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
<build>
<finalName>MyStartUp</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
I use tomcat server v7.0 to deploy and I use maven to build.
Whenever I make a change I go to maven terminal and use "mvn clean install" and go to localhost:8080/manager and deploy the war by browsing the application in my desktop. After this I see "MyStartUp" in tomcat manager window in browser.
My project name in eclipse looks as "mystartup".
When I add the project in Eclipse IDE using "Add or remove" after right click the server, I see "mystartup" and I add it. Then if I refresh localhost:8080/manager/
I see two different project deployed.
1) MyStartUp (Url : localhost:8080/MyStartUp --> Works)
2) mystartup (Url : localhost:8080/mystartup --> Doesn't Work)
When I click the second one, I am not able to access the application. But if I use the first one, it works
Because of this, each time, I do "mvn clean install" in IDE and I manually undeploy "MyStartUp" and deploy new install of "MyStartUp". This takes away my time. I want to add my project to Server in IDE and restart it when I make a change and run the application. How to fix this issue?
PS:
Here is my web.xml
<web-app version="2.2" id="WebApp_ID">
<!-- <display-name>Archetype Created Web Application</display-name> -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/mvc/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/WEB-INF/jsp/template.jsp</welcome-file>
</welcome-file-list>
</web-app>
This is how my git clone looks
git clone https://MyStartUp#bitbucket.org/MyStartUp/mystartup.git
I'm new to Glassfish and Java EE although I've been using Java for a few years. I've inherited a project that stalled and now I need to start development on it again. I'm trying to deploy the web application as-is to see what works and what needs attention. While there is a lot of code to implement various functions, it appears that the first point needing attention is deployment of the application.
The web application I'm trying to deploy is MyServer and is packaged in a WAR archive. A class in MyServer has a reference to a class in MyDatabase which implements an interface (InterfaceOne) from MyInterfaces. The class in MyServer also has a direct reference to InterfaceOne from MyInterfaces. MyServer, MyDatabase and MyInterfaces are all projects in Eclipse and packaged using Maven. The MyServer POM file lists MyDatabase as a dependency and the POM file for MyDatabase lists MyInterfaces as a dependency. The MyServer POM file doesn't list MyInterfaces as an immediate dependency but I don't think that this should cause an issue. Eclipse doesn't show any errors in the MyServer class concerned; Eclipse appears to consider the Maven dependencies to be sufficient to locate all necessary classes.
When I deploy the MyServer WAR on Glassfish v3.1.2 via the Admin web console and then view the logs in ~glassfish3/glassfish/domains/MyDomain/logs/server.log I encounter the following errors:
[#|2014-05-29T10:06:02.371+0100|SEVERE|glassfish3.1.2|global|_ThreadID=80;_ThreadName=Thread-2;| Class [ my/interfaces/InterfaceOne] not found. Error while loading [ class my.server.ControllerOne ]|#]
[#|2014-05-29T10:06:02.387+0100|SEVERE|glassfish3.1.2|global|_ThreadID=80;_ThreadName=Thread-2;|Class [ my/interfaces/InterfaceOne ] not found. Error while loading [ class my.server.ControllerOne ]|#]
There are two errors shown relating to the interface while trying to load the class from MyServer. If I remove either the reference to MyDatabase or the direct reference to InterfaceOne from MyInterfaces from the my.server.ControllerOne class then one of the errors above disappears (which is expected and just confirms that the error is related to the references (directly and indirectly) of the InterfaceOne from MyInterfaces.
Similar questions including here, here and here all mention ensuring that the required libraries (my-database.jar and my-interfaces.jar) are located in the WEB-INT/lib directory of the MyServer application's WAR archive. However, if I inspect the generated WAR archive for MyServer then the libraries are indeed located in the WEB-INF/lib/ directory. If I inspect the ~glassfish3/glassfish/domains/MyDomain/applications/MyServer/WEB-INF/lib/ directory after deployment the libraries are there too. I assume this indicates that they were successfully extracted from the WAR archive and placed on the Glassfish server. The point is the libraries are definitely there!
All I can think of is that the libraries are not added to classpath of the JVM trying to load the classes of MyServer but surely if Glassfish tries to load classes of an application then it should also first load the libraries packaged with the application shouldn't it? Indeed this page from the Oracle GlassFish Server Application Development Guide
Release 3.1.2 indicates that the WEB-INF/lib/ directory of an application is added to the application's classpath.
I've seen other suggestions that libraries required by web applications be placed in the ~glassfish3/glassfish/domains/MyDomain/lib/ext/ directory. That might very well work but my specific libraries are required by the MyServer application only, not the whole of MyDomain. As far as I can tell, it should be valid to place them in the WEB-INF/lib/ directory of my application.
Does anyone have any ideas about why the my-database.jar and my-interfaces.jar libraries don't seem to be added to the classpath during deployment? More specifically, does anyone know why the my.interfaces.InterfaceOne class isn't visible while loading the my.server.ControllerOne class during deployment?
MyServer's web.xml content:
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>MyServer</display-name>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
<welcome-file>default.xhtml</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/balusc.taglib.xml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
</web-app>
MyServer pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.webapp</groupId>
<artifactId>my-server</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>My Server</name>
<parent>
<groupId>my.webapp</groupId>
<artifactId>my-parent-pom</artifactId>
<version>1.5</version>
</parent>
<organization>
<name>Example</name>
<url>http://www.example.com</url>
</organization>
<repositories>
<repository>
<id>eclipselink</id>
<url>http://www.eclipse.org/downloads/download.php?r=1&nf=1&file=/rt/eclipselink/maven.repo/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>eclipselink</groupId>
<artifactId>eclipselink</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>utilities</groupId>
<artifactId>utilities</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>my.webapp</groupId>
<artifactId>my-database</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<!-- <configuration> section added to pick up the WEB-INF/web.xml inside
WebContent -->
<configuration>
<webResources>
<resource>
<directory>WebContent</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
<scm>
<connection>scm:svn:https://svn.server/location/in/repo/my_server</connection>
<developerConnection>scm:svn:https://svn.server/location/in/repo/my_server/trunk</developerConnection>
</scm>
</project>
MyDatabase pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>my-database</artifactId>
<version>0.1.0-SNAPSHOT</version>
<parent>
<groupId>my.webapp</groupId>
<artifactId>my-parent-pom</artifactId>
<version>1.5</version>
</parent>
<dependencies>
<dependency>
<groupId>eclipselink</groupId>
<artifactId>eclipselink</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>bcrypt</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>my.webapp</groupId>
<artifactId>my-interfaces</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_3.0_spec</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<scm>
<connection>scm:svn:https://svn.server/location/in/repo/my_database</connection>
<developerConnection>scm:svn:https://svn.server/location/in/repo/my_database/trunk/</developerConnection>
</scm>
<groupId>my.webapp</groupId>
</project>
MyInterfaces pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.webapp</groupId>
<artifactId>my-interfaces</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>my.webapp</groupId>
<artifactId>my-parent-pom</artifactId>
<version>1.5</version>
</parent>
<scm>
<connection>scm:svn:https://svn.server/location/in/repo/my_interfaces</connection>
<developerConnection>scm:svn:https://svn.server/location/in/repo/my_interfaces/trunk</developerConnection>
</scm>
<dependencies>
<dependency>
<groupId>my.webapp</groupId>
<artifactId>my-utilities</artifactId>
<version>0.1.2</version>
<classifier>me</classifier>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
The MyInterfaces POM lists a dependency on MyUtilities. I think this can be safely ignored for this question since none of it's classes appear in the error messages I've described. It is also placed in the WEB-INT/lib/ directory on the Glassfish server when my application is deployed.
(Glassfish questions appear to require a lot of info like web.xml files and pom.xml etc. Thanks for taking the time to sift through all of this.)
I have set up a project with basically the same structure as you described and I can't reproduce the problem nor do I have an additional idea what could be wrong.
Therefore I have pushed my test project to GitHub so you can try it and maybe you find any hint what is different in your project.
The project is here: https://github.com/erdbeerschnitzel/war-packaging
If you don't have a GitHub account to clone the project you can download the ZIP (button on the lower right). Extract it somewhere and load the 5 projects in your IDE, build everything and deploy the WAR file of the my-server project.
I left out the parent project and removed some dependencies like eclipselink and primefaces but I think that shouldn't make the difference.
Good luck.
Update:
Glassfish has separate Deploy and Launch actions. I'd expect Deploy to
upload, extract the WAR and register anything that needs to be
registered. I'd expect the Launch action to actually load classes and
start processes. Why are classes being loaded when I deploy?
Actually the application (and therefore the classes) is loaded when you deploy it.
It appears that there were two issues at play:
Firstly MyServer's web.xml <display-name> was incorrect. This
wasn't visible in my question because I'd changed the library names
(which contain client names). Part of the requirements given to me
for the project were to rebrand the project and I missed the
<display-name> element. Oops.
The second issue was that, while
investigating this issue, I moved the MyDatabase and
MyInterfaces libraries from the MyServer WEB-INF/lib/
directory to the domain's lib/ext/ directory and back. This
changed the errors logged during deployment (since the libraries
were visible despite the incorrect <display-name> but they errors
didn't reappear when I moved the database and interface libraries
back into the MyServer application. I think Glassfish was caching
the libraries and not updating the cached libraries during
deployment. Stopping/starting the domain updated the cache.
To summarise, once the <display-name> of MyServer was changed and the Glassfish library cache was updated, the class loading errors appear resolved.
I am trying to develop a basic Restful service using Jersey Maven and Eclipse.
I am following the example given here.
I followed the steps as given in the link but when I try to run the project I get a Request Resource Not available error.
This is my modified dependency in pom.xml file
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
and modified Build in pom.xml
<finalName>maven.secondrest</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.0-beta-1</version>
<configuration>
<port>9999</port>
<path>/</path>
<warFile>${project.basedir}/target/${project.build.finalName}.war</warFile>
</configuration>
</plugin>
</plugins>
The web.xml is very much the same as given in the example:
<display-name>Restful Web Application</display-name>
<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>rest.model</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>
and this is altered java code:
package rest.model;
//imports
#Path("/hello")
public class HelloWorldService {
#GET
#Path("/{param}")
public Response getMsg(#PathParam("param") String msg) {
String output = "Jersey say : " + msg;
return Response.status(200).entity(output).build();
}
}
I am trying to run it by using: mvn tomcat:run
When I enter localhost:9999 it displays a message "Hello World". But when I enter the url as given in the example I get a resource not found error.
This is the url I run: http://localhost:9999/maven.secondrest/rest/hello/nelo
I seems like I was using the URL incorrectly. The correct URL to access this service would be localhost:9999/rest/hello/nelo. That is, leaving out the project name as it has already been mentioned in the plugin.
My problem is that even set the "Deployment Assembly" to include the maven dependencies, this giving that my class is not being found, I do not know what else to do.
And I'm just noticing that with the ContextLoaderListener class since other classes seem to be included in my package.
My file pom.xml
<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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mkyong.common</groupId>
<artifactId>SpringMVC</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringMVC Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId>
<version>3.8.1</version> <scope>test</scope> </dependency> -->
<!-- Spring framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>
<!-- Spring MVC framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>2.5.6</version>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- for compile only, your container should have this -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>SpringMVC</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.0-beta-1</version>
<configuration></configuration>
</plugin>
</plugins>
</build>
</project>
My file web.xml
<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>Spring Web MVC Application</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
This problem seems to be either due to:
Some library version mismatch (ie. java version to compile != java
version on web app server).
Required Spring library not included during deployment.
Maven archetypes used to setup the project
Perform these steps to try fix this issue:
In pom.xml > if you use maven-compiler-plugin, double check this is matching the version of the library used, if not change it (ie. 1.7 NOT 1.6).
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
If you changed the library version in the above step, you then must do: Right Click on Project > Maven > Update Project... If an error is thrown during this step, you may find yourself stuck for good. I had this issue and could not resolve it. I ended up giving up creating my "Spring MVC with Maven" in Eclipse using archetypes. I believe using archetypes messed things up..in my case.
Right Click on Project > Properties > Java Build Path > JRE System Library > Edit > choose correct library version
Right Click on Project > Properties > Project Facets > Dynamic Web module (should be checked) > Runtimes tab on the right side of the panel > choose the server created (you must have added a server previously).
Right Click on Project > Properties > Deployment Assembly > Add > Java Build Path Entries > select the Spring dependencies. This is from ClassNotFoundException while loading ContextLoaderListener Note: You must perform this step every time after doing a "Maven > Update Project" in eclipse
Remember to clean your project before to deploy it: Project > Clean
... > select project > clean
Deploy your project and see it NOT break... hopefully
In my case, I had to restart a new project without using maven archetypes to get going. I used these guidelines http://gkokkinos.wordpress.com/2012/01/02/setting-up-a-spring-mvc-project-with-maven-in-eclipse/ . I still had an error thrown, but adding the Spring dependencies via Deployment Assembly (as described above) fixed things up.
I had this same problem. Simple solution is to right click the top level project -> Properties -> Deployment Assembly and include the 'Maven Dependencies'. In my case this is where my problem was. The class DispatcherServlet was not being included in the war file, therefore it was not found by Tomcat when I deployed it to that server.
I had similar issue and followed these steps to fix it.
Open Server tab in eclipse. Right click on your server.
Clean (Tomcat) Work directory
Clean (this is different than Work directory clean up which you could see in right click context)