Issues with Swagger integration into a Tomcat 8, Hibernate, and Jersey setup

1,289 views
Skip to first unread message

Macon Suckow

unread,
Jun 30, 2014, 2:13:29 PM6/30/14
to swagger-sw...@googlegroups.com
I'm trying to setup Swagger with a web project that uses Jersey, Hibernate, and Tomcat 8. I have been unsuccessful into getting it to start and get something other than a 404. My web app runs fine and starts fine, but the Swagger information has not been able to start. I'm using Netbeans too.

Project Setup:



Swagger Servlet:
package messages;

import com.wordnik.swagger.config.ConfigFactory;
import com.wordnik.swagger.config.ScannerFactory;
import com.wordnik.swagger.config.SwaggerConfig;
import com.wordnik.swagger.jaxrs.config.DefaultJaxrsScanner;
import com.wordnik.swagger.jaxrs.reader.DefaultJaxrsApiReader;
import com.wordnik.swagger.reader.ClassReaders;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;

@WebServlet(name = "SwaggerConfigSms", loadOnStartup = 1)
public class SwaggerConfigSms extends HttpServlet{
    @Override
    public void init(ServletConfig servletConfig) {
        try {
            System.out.println("Got to config");
            super.init(servletConfig);
            SwaggerConfig swaggerConfig = new SwaggerConfig();
            ConfigFactory.setConfig(swaggerConfig);
            swaggerConfig.setBasePath("http://localhost:8088/sms/rest");
            swaggerConfig.setApiVersion("1.0.0");
            ScannerFactory.setScanner(new DefaultJaxrsScanner());
            ClassReaders.setReader(new DefaultJaxrsApiReader());
        } catch (ServletException e) {
            System.out.println(e.getMessage());
        }
    }
}


Web.xml

...
    <servlet>
        <servlet-name>RestServlet</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>messages;</param-value>
            <!--com.wordnik.swagger.jaxrs.listings-->
        </init-param>
    </servlet>
<servlet>
        <servlet-name>SwaggerConfigSms</servlet-name>
        <servlet-class>messages.SwaggerConfigSms</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>RestServlet</servlet-name>
        <url-pattern>/rs/*</url-pattern>
    </servlet-mapping>
...

Pom.xml
...
<dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
        
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.17.1</version>
        </dependency>
        
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.17.1</version>
        </dependency>
        
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-servlet</artifactId>
            <version>1.17.1</version>
        </dependency>
        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-servlet_2.10</artifactId>
            <version>1.3.5</version>
        </dependency>
        
        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-jersey-jaxrs_2.10</artifactId>
            <version>1.3.5</version>
        </dependency>
...

Example Resource:
@Api(value = "/apimessage", description = "The apimessage API")
@Path("/apimessage")
public class ApiMessageResource {
@Context
ServletContext application;
EntityManager entityManager;
@POST
        @ApiOperation(value = "Create a new message", notes = "Creates a new message and persists in the database")
@ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid ID supplied"), @ApiResponse(code = 404, message = "Message not found")})
        @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ApiMessage createMessage(ApiMessage message) throws Exception {
                 ... my code...
        }


**Tomcat is running my web app on port 8088

Thanks for any help in advance, this is also my first post here, so if there are any formatting or standards I missed, please feel free to let me know!


Ron

unread,
Jun 30, 2014, 2:28:28 PM6/30/14
to swagger-sw...@googlegroups.com
Hi and welcome to Swagger!

First off, please get rid of the swagger-servlet dependency. You don't need that if you're using jersey/jax-rs.

Can you give a few more details about what you're trying to do? Which URL do you browse to?


--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Macon Suckow

unread,
Jun 30, 2014, 3:09:29 PM6/30/14
to swagger-sw...@googlegroups.com
Okay I can do that, so right now we have 4 routes that a user can hit "/summary, /apimessage, /facility, and /person" Those work all fine and dandy thanks to Jersey and I'm just looking for a route that I can hit for swagger to show up. Right now for the /apimessage for example the URL i would hit is:

It would be nice and convenient if swagger could be deployed to something like:
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.

Ron

unread,
Jun 30, 2014, 3:11:57 PM6/30/14
to swagger-sw...@googlegroups.com
by default, swagger would be deployed at /api-docs at the root of your application. so if your application is deployed to http://localhost:8088/sms then swagger would be available at http://localhost:8088/sms/api-docs


To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Macon Suckow

unread,
Jun 30, 2014, 3:24:17 PM6/30/14
to swagger-sw...@googlegroups.com
Wow, I can't believe I never tried that... Thanks haha, but now how do I get rid of the "Swagger Sample App" and have my own RESTful app generate its JSON?
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Ron

unread,
Jun 30, 2014, 3:25:39 PM6/30/14
to swagger-sw...@googlegroups.com
I don't know what you're referring to...


To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Macon Suckow

unread,
Jun 30, 2014, 3:34:27 PM6/30/14
to swagger-sw...@googlegroups.com
Haha ya thats fair, I wasn't being very descriptive. Anyway I cloned wordnik/swagger-ui to get the css files and all that and it defaulted when I hit the URL for the api-docs to hittings his site, once I changed the URL on the Swagger page to my own I got "Can't read from server. It may not have the appropriate access-control-origin settings."

Have you seen that before? Does that help make any sense?

Ron

unread,
Jun 30, 2014, 3:36:00 PM6/30/14
to swagger-sw...@googlegroups.com
Yes, you need to enable CORS support in your application - https://github.com/wordnik/swagger-core/wiki/CORS


To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Macon Suckow

unread,
Jun 30, 2014, 5:00:39 PM6/30/14
to swagger-sw...@googlegroups.com
So the rest of it looks good enough? The way that the SwaggerConfigSms.java looks and how the servlet is hooked up? Because the examples you pointed me to have it setup differently


You received this message because you are subscribed to a topic in the Google Groups "Swagger" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/swagger-swaggersocket/eYyhwm5fU6c/unsubscribe.
To unsubscribe from this group and all its topics, send an email to swagger-swaggers...@googlegroups.com.

Macon Suckow

unread,
Jun 30, 2014, 10:33:57 PM6/30/14
to swagger-sw...@googlegroups.com
I have removed the swagger servlet so that my pom.xml looks like this:
...
        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-jersey-jaxrs_2.10</artifactId>
            <version>1.3.5</version>
        </dependency>
        
        <dependency>
            <groupId>com.thetransactioncompany</groupId>
            <artifactId>cors-filter</artifactId>
            <version>1.3.2</version>
        </dependency>
...

web.xml:
...
<servlet>
        <servlet-name>RestServlet</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>messages;</param-value>
        </init-param>
    </servlet>
    
    <servlet>
        <servlet-name>JerseyJaxrsConfig</servlet-name>
        <servlet-class>com.wordnik.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:8088/sms</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <filter>
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
        <init-param>
            <param-name>cors.allowGenericHttpRequests</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
                <param-name>cors.allowOrigin</param-name>
                <param-value>*</param-value>
        </init-param>
        <init-param>
                <param-name>cors.allowSubdomains</param-name>
                <param-value>false</param-value>
        </init-param>
        <init-param>
                <param-name>cors.supportedMethods</param-name>
                <param-value>GET, HEAD, POST, PUT, OPTIONS</param-value>
        </init-param>
        <init-param>
                <param-name>cors.supportsCredentials</param-name>
                <param-value>true</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
      <filter-name>CORS</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    <servlet-mapping>
        <servlet-name>RestServlet</servlet-name>
        <url-pattern>/rs/*</url-pattern>
    </servlet-mapping>
...

Once I connect to http://localhost:8088/sms/api-docs I get swagger to show up but all it says is "fetching resource list: http://localhost:8088/sms/api-docs". I went into the console to see if I could diagnose anything myself and I noticed that Uncaught SyntaxError: Unexpected token < (index):1.

My hunch is that its trying to parse xml? But if thats the case, how does one change it so it generates json?

Also, do I need to write the json that swagger reads, or is it supposed to generate everything it needs?

Thanks in advance.

Ron

unread,
Jul 1, 2014, 2:12:22 AM7/1/14
to swagger-sw...@googlegroups.com
The first step would be to check that you're getting the correct response from http://localhost:8088/sms/api-docs without swagger-ui (just via your browser).
If that's the case, and you're getting that error, please share your swagger json output so we can try analyzing it.
Swagger core doesn't generate xml in any configuration so that's not an issue.

Swagger-core generates the swagger files dynamically based on the configuration and annotations in your code. There's no need to manually modify the output.


Macon Suckow

unread,
Jul 1, 2014, 8:00:27 AM7/1/14
to swagger-sw...@googlegroups.com

I guess that raises another question. How do I view the output? I've only been able to see that fetching list message in the browser

You received this message because you are subscribed to a topic in the Google Groups "Swagger" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/swagger-swaggersocket/eYyhwm5fU6c/unsubscribe.
To unsubscribe from this group and all its topics, send an email to swagger-swaggers...@googlegroups.com.

Ron

unread,
Jul 1, 2014, 8:17:51 AM7/1/14
to swagger-sw...@googlegroups.com
That would give you a list of resources, like here - http://petstore.swagger.wordnik.com/api/api-docs/
Then, for each resource, you can open its own documentation.
In the above pet store example, you can reach the pet operations by going to http://petstore.swagger.wordnik.com/api/api-docs/pet

Macon Suckow

unread,
Jul 1, 2014, 9:27:04 AM7/1/14
to swagger-sw...@googlegroups.com
So you might have to talk to me like a 4 year old here, since i'm pretty new to this whole thing. But I can't just get the json, that the problem. I have tried moving the swagger-ui stuff out of the project so i can view the json and send to you, but all i get everytime i go to that url i get the fetching error.

Ron

unread,
Jul 1, 2014, 9:33:58 AM7/1/14
to swagger-sw...@googlegroups.com
Don't worry about it.

Let's give you a brief overview of some of the terms.

Swagger is a REST API documentation specification. It is not a specific piece of software. There are implementations and tools created to support the spec.

Swagger-core is the library you use within your application to automatically generate the swagger specification json of your API at runtime (that is, it changes with your code and doesn't actually create files).

Swagger-UI is a presentation and testing tool that reads swagger specification jsons and does its pretty magic with it.

Normally, people try to use Swagger-UI before they check that their application produces the swagger json properly first.
So for now, let's put swagger-ui aside and check your application.
Considering this is Tomcat, I assume 'sms' is the context root of your application (correct me if I'm wrong). What response do you get when you open http://localhost:8088/sms/api-docs?

Macon Suckow

unread,
Jul 1, 2014, 9:42:14 AM7/1/14
to swagger-sw...@googlegroups.com
Okay, all of that makes sense, what all should i remove from the api-docs folder to not load the swagger ui? Does the index.html need to change or is there a file that needs to be removed?



On Monday, June 30, 2014 1:13:29 PM UTC-5, Macon Suckow wrote:

Ron

unread,
Jul 1, 2014, 9:47:49 AM7/1/14
to swagger-sw...@googlegroups.com
what api-docs folder? you're not supposed to have such a folder. just check what that url I gave you returns first.


Macon Suckow

unread,
Jul 1, 2014, 9:54:09 AM7/1/14
to swagger-sw...@googlegroups.com
That just shows the fetching list error, so if I'm supposed to have an actual api-docs folder in the root of the project then i will remove it and I will define the url for that in the <servlet> part of web.xml?


--
You received this message because you are subscribed to a topic in the Google Groups "Swagger" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/swagger-swaggersocket/eYyhwm5fU6c/unsubscribe.
To unsubscribe from this group and all its topics, send an email to swagger-swaggers...@googlegroups.com.

Ron

unread,
Jul 1, 2014, 9:55:27 AM7/1/14
to swagger-sw...@googlegroups.com
Okay, let's go back a step.
How did you configure Swagger in your application?

Macon Suckow

unread,
Jul 1, 2014, 10:00:02 AM7/1/14
to swagger-sw...@googlegroups.com
Well I thought I needed some actual files, so I cloned a sample project that wordnik had and used that api-docs folder. So that makes sense why it wasn't connecting to mine is because it was using already made json things for that sample. Anyway, after that I added 
        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-jersey-jaxrs_2.10</artifactId>
            <version>1.3.5</version>
        </dependency>
to my pom.xml and 
<servlet>
        <servlet-name>JerseyJaxrsConfig</servlet-name>
        <servlet-class>com.wordnik.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:8088/sms/api-docs</param-value>
to the web.xml

Thats it, I have a hunch I missed a step though.

Ron

unread,
Jul 1, 2014, 10:06:06 AM7/1/14
to swagger-sw...@googlegroups.com
Can you show the full web.xml?

Macon Suckow

unread,
Jul 1, 2014, 10:07:53 AM7/1/14
to swagger-sw...@googlegroups.com
<web-app> 
    
    <display-name>MyWebProject</display-name>
    <context-param>
        <param-name>pu-name</param-name>
        <param-value>mydb</param-value>  
    </context-param>
    <listener>
        <listener-class>messages.ContextListener</listener-class>
    </listener>
    
    <servlet>
        <servlet-name>RestServlet</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>messages;</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>RestServlet</servlet-name>
        <url-pattern>/rs/*</url-pattern>
    </servlet-mapping>
    <resource-ref>
        <res-ref-name>jdbc/mydb</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>
   
</web-app>

Ron

unread,
Jul 1, 2014, 10:12:09 AM7/1/14
to swagger-sw...@googlegroups.com
You need to add com.wordnik.swagger.jaxrs.json;com.wordnik.swagger.jaxrs.listing to your init param.

Macon Suckow

unread,
Jul 1, 2014, 10:17:47 AM7/1/14
to swagger-sw...@googlegroups.com
Alright, so i added those, but now i just get a 404 when i hit http://localhost:8088/sms/api-docs even though it matches what I told it for the base-url

Ron

unread,
Jul 1, 2014, 10:22:58 AM7/1/14
to swagger-sw...@googlegroups.com

Macon Suckow

unread,
Jul 1, 2014, 10:25:05 AM7/1/14
to swagger-sw...@googlegroups.com
Oh.. you're a genius haha. So now its {"apiVersion":"1.0.0","swaggerVersion":"1.2","apis":[{"path":"/apimessage","description":"The apimessage API"}]} which is correct because i've only annotated this one file.

SO THAT WORKS!!

Since I want to keep pestering you, how does one start the ui then?

Ron

unread,
Jul 1, 2014, 10:33:12 AM7/1/14
to swagger-sw...@googlegroups.com
Now open the UI and point it at http://localhost:8088/sms/rs/api-docs

Macon Suckow

unread,
Jul 1, 2014, 10:35:44 AM7/1/14
to swagger-sw...@googlegroups.com
What do you mean by "open the UI"?

Macon Suckow

unread,
Jul 1, 2014, 10:37:11 AM7/1/14
to swagger-sw...@googlegroups.com
Because when i hit that url i just get the json

Ron

unread,
Jul 1, 2014, 10:38:26 AM7/1/14
to swagger-sw...@googlegroups.com
The index.html from the Swagger-UI project.

Macon Suckow

unread,
Jul 1, 2014, 10:41:45 AM7/1/14
to swagger-sw...@googlegroups.com
Where do I put that index.html at in the project structure, in the WEB-INF or the META-INF? And do I need all those css, and other folders too?

Ron

unread,
Jul 1, 2014, 10:42:43 AM7/1/14
to swagger-sw...@googlegroups.com
For now, just open it in your browser. Don't deploy it.

Macon Suckow

unread,
Jul 1, 2014, 10:45:02 AM7/1/14
to swagger-sw...@googlegroups.com
Oh okay, nice that works. What do you suggest do for deploying it?

Ron

unread,
Jul 1, 2014, 10:48:51 AM7/1/14
to swagger-sw...@googlegroups.com
Copy the files from the /dist dir to your webapp dir.

Macon Suckow

unread,
Jul 1, 2014, 10:59:22 AM7/1/14
to swagger-sw...@googlegroups.com
Okay so I copied all the files into WEB-INF so it has folders (lib, images, css) and files (web.xml, swagger-ui.min, swagger-ui, o2c.html, and index.html) and that lib folder has a few jars the some swagger things. but when i hit http://localhost:8088/sms/rs/api-docs I still just get the json

Ron

unread,
Jul 1, 2014, 11:01:54 AM7/1/14
to swagger-sw...@googlegroups.com
Also, not the WEB-INF directory but the webapp directory (since you're using maven).

Macon Suckow

unread,
Jul 1, 2014, 11:10:10 AM7/1/14
to swagger-sw...@googlegroups.com
Awesome! that second url is the one that works. So theoretically everything is hooked up and once I start documenting more of the api's it will update once i re-deploy and all that?

Ron

unread,
Jul 1, 2014, 11:10:56 AM7/1/14
to swagger-sw...@googlegroups.com

That is correct.

Macon Suckow

unread,
Jul 1, 2014, 11:12:09 AM7/1/14
to swagger-sw...@googlegroups.com
Perfect, thank you so much for being patient with me and helping me walk through this! 
Reply all
Reply to author
Forward
0 new messages