Swagger and Java Servlets

3,528 views
Skip to first unread message

Marco Denisi

unread,
May 15, 2014, 1:40:35 PM5/15/14
to swagger-sw...@googlegroups.com
Hi, 
I'm developing a Java Dynamic Web Project using Eclipse. This project is just a web service which has some servlets listening on some path. 
So, I have classes like this:

public class ClassName extends HttpServlet{
       protected void doGet(HttpServletRequest request, HttpServletResponse response) {
                ... some computation
       } 
}

I'd like to make some beautiful documentation using Swagger. But I can't do it! I read 100 times the quickstart guide for Java + Servlet but nothing. Here's what i did:

1) in my web.xml, i put all the initialization stuff. Here's the code

<?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>MyWebService</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  
  <!-- swagger servlet reader -->
<servlet>
  <servlet-name>DefaultServletReaderConfig</servlet-name>
  <servlet-class>com.wordnik.swagger.servlet.config.DefaultServletReaderConfig</servlet-class>
  <init-param>
    <param-name>swagger.resource.package</param-name>
    <param-value>servlet.users</param-value>
  </init-param>
  <init-param>
    <param-name>swagger.api.basepath</param-name>
    <param-value>http://localhost:8080/ISellToYouRESTWebService</param-value>
  </init-param>
  <init-param>
    <param-name>api.version</param-name>
    <param-value>1.0.0</param-value>
  </init-param>
  <load-on-startup>2</load-on-startup>
</servlet>
  
  <!-- swagger api declaration -->
<servlet>
  <servlet-name>ApiDeclarationServlet</servlet-name>
  <servlet-class>com.wordnik.swagger.servlet.listing.ApiDeclarationServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>ApiDeclarationServlet</servlet-name>
  <url-pattern>/api-docs/*</url-pattern>
</servlet-mapping>
       <!-- other servlet declaration --> 
  </web-app>
2) I add some annotation. Just a little note: I had to guess, there's an huge lack of documentation for simple Java servlets

@Api(value = "/sample/users", description = "gets some data from a servlet")
public class CreateUser extends HttpServlet{
private static final long serialVersionUID = 1L;
@ApiOperation(
    value = "It's an operation",
    notes = "something",
    httpMethod = "GET")
@ApiParamsImplicit (value = { @ApiParamImplicit(name = "name", value = "The name of the user"), 
@ApiParamImplicit(name = "surname", value = "The surname of the user") })
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    ...
}
} 
3) I deployed this on a server (I'm using Tomcat 7) and.... ERROR! 
mag 15, 2014 7:19:28 PM org.apache.catalina.core.StandardService startInternal
Informazioni: Starting service Catalina
mag 15, 2014 7:19:28 PM org.apache.catalina.core.StandardEngine startInternal
Informazioni: Starting Servlet Engine: Apache Tomcat/7.0.52
mag 15, 2014 7:19:29 PM org.apache.catalina.core.ApplicationContext log
Informazioni: Marking servlet DefaultServletReaderConfig as unavailable
mag 15, 2014 7:19:29 PM org.apache.catalina.core.StandardContext loadOnStartup
Grave: Servlet /ISellToYouRESTWebService threw load() exception
java.lang.ClassNotFoundException: scala.ScalaObject
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1718)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2944)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1208)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1688)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569)
at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:529)
at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:511)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:139)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1143)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5210)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5493)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744) 

I'm sure it's a stupid error, but I can't understand where it is.

Thanks in advance

Marco 

Ron

unread,
May 15, 2014, 1:57:59 PM5/15/14
to swagger-sw...@googlegroups.com
That looks like a dependency issue. Do you use maven? If so, can you share your pom?
If not, can you share the libs you include with your WAR?


--
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.

Marco Denisi

unread,
May 15, 2014, 2:19:31 PM5/15/14
to swagger-sw...@googlegroups.com
I'm not using Maven and sure, here are my libs:

swagger-annotation_2.9.1-1.0.2.jar
swagger-core-1.0.jar
swagger-servlet_2.9.1-1.3.0-RC2.jar

Marco

Ron

unread,
May 15, 2014, 2:22:08 PM5/15/14
to swagger-sw...@googlegroups.com
You're missing way too many dependencies, and using old jars.

My suggestion is to clone the swagger-core repository and build this sample - https://github.com/wordnik/swagger-core/tree/master/samples/scala-servlet
Then use the libraries it pulls in your application and try again.


--

Marco Denisi

unread,
May 15, 2014, 3:27:17 PM5/15/14
to swagger-sw...@googlegroups.com
I've built it and took all the jars in the lib's folder and it seems to work! Thanks! But now I've another question. I made a new project to try swagger. I have this 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>ProvaSwagger</display-name>

  <welcome-file-list>

    <welcome-file>index.html</welcome-file>

  </welcome-file-list>

  

  <!-- swagger servlet reader -->

<servlet>

  <servlet-name>DefaultServletReaderConfig</servlet-name>

  <servlet-class>com.wordnik.swagger.servlet.config.DefaultServletReaderConfig</servlet-class>

  

  <init-param>

    <param-name>swagger.resource.package</param-name>

    <param-value>com.wordnik.swagger.sample.servlet</param-value>

  </init-param>

  <init-param>

    <param-name>swagger.api.basepath</param-name>

    <param-value>http://localhost:8080/ProvaSwagger</param-value>

  </init-param>

  <init-param>

    <param-name>api.version</param-name>

    <param-value>1.0.0</param-value>

  </init-param>

  <load-on-startup>2</load-on-startup>

</servlet>


<!-- swagger api declaration -->

<servlet>

  <servlet-name>ApiDeclarationServlet</servlet-name>

  <servlet-class>com.wordnik.swagger.servlet.listing.ApiDeclarationServlet</servlet-class>

</servlet>

<servlet-mapping>

  <servlet-name>ApiDeclarationServlet</servlet-name>

  <url-pattern>/api-docs/*</url-pattern>

</servlet-mapping>



</web-app>

and only one servlet, that is

@Api(value = "/sample/users", description = "gets some data from a servlet")
public class Prova extends HttpServlet{

private static final long serialVersionUID = 1L;
@ApiOperation(
    value = "Add a new pet to the store",
    notes = "this adds pets nicely",
    httpMethod = "GET")
@ApiImplicitParams(value = { @ApiImplicitParam(name = "name", value = "A name"),
@ApiImplicitParam(name = "surname", value = "A surname")})

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
}

} 
when go to the link http://localhost:8080/ProvaSwagger/api-docs here's what appear:
{"apiVersion":"1.0.0","swaggerVersion":"1.2"} 
why I can't see the "Prova"'s api? 

Ron

unread,
May 15, 2014, 3:49:50 PM5/15/14
to swagger-sw...@googlegroups.com
<param-name>swagger.resource.package</param-name>

    <param-value>com.wordnik.swagger.sample.servlet</param-value>


The <param-value> needs to be the package of your servlet.



--

Marco Denisi

unread,
May 15, 2014, 4:24:36 PM5/15/14
to swagger-sw...@googlegroups.com
Fixed it. But still not working! 
I have to use Maven maybe?

Here's is the console output when i call the api-docs servlet

22:19:16.976 [http-bio-8080-exec-3] DEBUG org.reflections.Reflections - going to scan these urls:

file:/Volumes/Macintosh%20HD/Documents/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/ProvaSwagger/WEB-INF/classes/
22:19:17.069 [http-bio-8080-exec-3] INFO  org.reflections.Reflections - Reflections took 91 ms to scan 1 urls, producing 2 keys and 4 values 
22:19:17.123 [http-bio-8080-exec-3] DEBUG c.w.s.servlet.config.ServletReader - read routes from classes: /user, /show
22:19:17.129 [http-bio-8080-exec-3] DEBUG c.w.s.servlet.config.ServletReader - read routes from classes: /, createUser

Marco Denisi

unread,
May 16, 2014, 4:54:13 AM5/16/14
to swagger-sw...@googlegroups.com
Today I've tried to make another attempt, but this time i used maven. Here's the steps i followed:
1) From Eclipse, I created a new dynamic web project (named OtherTry) 
2) i transformed it into a maven project by right clicking on it
3) i followed the instruction on your wiki. So i put the dependency in the 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>OtherTry</groupId>
  <artifactId>OtherTry</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.3</version>
        <configuration>
          <warSourceDirectory>WebContent</warSourceDirectory>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
  <dependency>
  <groupId>com.wordnik</groupId>
  <artifactId>swagger-servlet_2.9.1</artifactId>
  <version>1.3.0-RC3</version>
  </dependency>
  </dependencies>
</project>

and i mapped the servlet properly in the 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>OtherTry</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  
  <!-- swagger servlet reader -->
<servlet>
  <servlet-name>DefaultServletReaderConfig</servlet-name>
  <servlet-class>com.wordnik.swagger.servlet.config.DefaultServletReaderConfig</servlet-class>
  <init-param>
    <param-name>swagger.resource.package</param-name>
    <param-value>servlet.user</param-value>
  </init-param>
  <init-param>
    <param-name>swagger.api.basepath</param-name>
    <param-value>http://localhost:8080/OtherTry/api-docs</param-value>
  </init-param>
  <init-param>
    <param-name>api.version</param-name>
    <param-value>1.0.0</param-value>
  </init-param>
  <load-on-startup>2</load-on-startup>
</servlet>
<!-- swagger api declaration -->
<servlet>
  <servlet-name>ApiDeclarationServlet</servlet-name>
  <servlet-class>com.wordnik.swagger.servlet.listing.ApiDeclarationServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>ApiDeclarationServlet</servlet-name>
  <url-pattern>/api-docs/*</url-pattern>
</servlet-mapping>
<servlet>
  <servlet-name>Prova</servlet-name>
  <servlet-class>servlet.user.Prova</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>Prova</servlet-name>
  <url-pattern>/user</url-pattern>
</servlet-mapping>
</web-app>

Then I've annotated my servlets.

@Api(value = "/user", description = "gets some data from a servlet")
public class Prova extends HttpServlet {

private static final long serialVersionUID = 1L;
@ApiOperation(httpMethod = "GET", value = "Resource to get a user")
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "User's name", required = true, dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "email", value = "User's email", required = true, dataType = "string", paramType = "query"),
})
@Override

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
System.out.println("HERE");
}
}

4) Every time i go to localhost:8080/OtherTry/api-docs i see only
{"apiVersion":"1.0.0","swaggerVersion":"1.2"}



What's the matter with me???

Ron

unread,
May 16, 2014, 5:58:47 AM5/16/14
to swagger-sw...@googlegroups.com

Unfortunately that wiki Is not up to date. You should copy the dependency from the sample I shared with you yesterday.

Also, what's the package of your servlet?

--

Marco Denisi

unread,
May 16, 2014, 9:55:45 AM5/16/14
to swagger-sw...@googlegroups.com
When i try to copy the dependencies in the pom.xml of the sample I get 3 errors in my pom. 
The package is servlet.user , so the param in correct...

Have you some java example?

Ron

unread,
May 16, 2014, 11:06:15 AM5/16/14
to swagger-sw...@googlegroups.com
    <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>


--

Marco Denisi

unread,
May 17, 2014, 4:08:07 AM5/17/14
to swagger-sw...@googlegroups.com
Thanks Ron, but it still show me the same thing.

I'm afraid I've to forget it!

Ron

unread,
May 17, 2014, 4:10:10 AM5/17/14
to swagger-sw...@googlegroups.com
Is this a project you can share? Or create a test project I can have a look it? It really shouldn't be a problem to solve it.
If you want, you can also join me on IRC @ #swa...@irc.freenode.net and I could help you online directly instead of going back and forth in emails.


On Sat, May 17, 2014 at 11:08 AM, Marco Denisi <marcod...@gmail.com> wrote:
Thanks Ron, but it still show me the same thing.

I'm afraid I've to forget it!

--

Marco Denisi

unread,
May 19, 2014, 3:31:17 AM5/19/14
to swagger-sw...@googlegroups.com
The main project contains a lot of classes, I think it can only be confusing!!! But I can share with you my test project in which I'm trying to use Swagger. 

The GitHub repo is


Thanks a lot

Marco Denisi

unread,
May 20, 2014, 2:34:19 PM5/20/14
to swagger-sw...@googlegroups.com
Hi Ron,
Do you have any good news for me? Or maybe we can get in touch on your IRC channel. Have you any favourite schedule?

Marco

Ron

unread,
May 21, 2014, 7:20:31 AM5/21/14
to swagger-sw...@googlegroups.com
Hi Marco,

Please perform the following two changes -
  1. Change the path in the @Api annotation. The first part of the path is used for the resource name. So if you want to keep it as "prova" add a "/" at the end.
    @Api(value = "/prova/", description = "gets some data from a servlet")
  2. Change the doGet method signature to public rather than protected:
      public void doGet(HttpServletRequest request, HttpServletResponse response)  {

These two together should get it to work.

Please let me know how it goes.

Ron



--

Marco Denisi

unread,
May 21, 2014, 9:27:45 AM5/21/14
to swagger-sw...@googlegroups.com
it worked!!!!

Thanks a lot!!!


--
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/JHJgQysLt58/unsubscribe.
To unsubscribe from this group and all its topics, send an email to swagger-swaggers...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages