GithubHelp home page GithubHelp logo

kongchen / swagger-maven-plugin Goto Github PK

View Code? Open in Web Editor NEW
758.0 47.0 448.0 2.09 MB

JAX-RS & SpringMVC supported maven build plugin, helps you generate Swagger JSON and API document in build phase.

Home Page: http://kongchen.github.io/swagger-maven-plugin/

License: Apache License 2.0

Java 79.11% HTML 20.81% Kotlin 0.07%

swagger-maven-plugin's Introduction

Swagger Maven Plugin

Build Status Maven Central

This plugin enables your Swagger-annotated project to generate Swagger specs and customizable, templated static documents during the maven build phase. Unlike swagger-core, swagger-maven-plugin does not actively serve the spec with the rest of the application; it generates the spec as a build artifact to be used in downstream Swagger tooling.

Features

Versions

  • 3.1.0 supports Swagger Spec 2.0, support JAX-RS & SpingMVC. (ACTIVE!)
  • 3.0.1 supports Swagger Spec 2.0, support JAX-RS & SpingMVC. (ACTIVE!)
  • 2.3.4 supports Swagger Spec 1.2, support JAX-RS & SpringMVC. (Lazily maintained)
  • 1.1.1 supports Swagger Spec 1.1. (No longer maintained)

Upgrading from 3.0.1 to 3.1.0+

Version 3.1.0+ of this plugin depends on the re-packaged/re-branded io.swagger.swagger-core dependency, which is formerly known as com.wordnik.swagger-core. If you use 3.1.0+, you must use the swagger-core dependency in the io.swagger namespace instead of the com.wordnik namespace, which is deprecated. You may see an example of migrating a project from 3.0.1 to 3.1.0 in the swagger-maven-plugin example project.

Usage

Import the plugin in your project by adding following configuration in your plugins block:

<build>
	<plugins>
		<plugin>
			<groupId>com.github.kongchen</groupId>
			<artifactId>swagger-maven-plugin</artifactId>
			<version>${swagger-maven-plugin-version}</version>
			<configuration>
				<apiSources>
					<apiSource>
						...
					</apiSource>
				</apiSources>
			</configuration>
			<executions>
				<execution>
					<phase>compile</phase>
					<goals>
						<goal>generate</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

The executions block is used to specify the phase of the build lifecycle you want the plugin to be executed in.

Configuration for configuration

name description
skipSwaggerGeneration If true, swagger generation will be skipped. Default is false. User property is swagger.skip.
apiSources List of apiSource elements. One apiSource can be considered as a version of APIs of your service. You can specify several apiSource elements, though generally one is enough.

Configuration for apiSource

name description
springmvc Tell the plugin your project is a JAX-RS(false) or a SpringMvc(true) project
locations required Classes containing Swagger's annotation @Api, or packages containing those classes can be configured here. Each item must be located inside a tag. Example: <locations><location>com.github.kongchen.swagger.sample.wordnik.resource</location><location>com.github.kongchen.swagger.sample.wordnik.resource2</location></locations>
schemes The transfer protocol of the API. Values MUST be from the list: "http", "https", "ws", "wss". Each value must be located inside its own <scheme> tag. Example: <schemes><scheme>http</scheme><scheme>https</scheme></schemes>
host The host (name or IP) serving the API. This MUST be the host only and does not include the scheme nor sub-paths. It MAY include a port. The host does not support path templating.
basePath The base path on which the API is served, which is relative to the host. The value MUST start with a leading slash (/). The basePath does not support path templating.
descriptionFile A Path to file with description to be set to Swagger Spec 2.0's info Object
info required The basic information of the api, using same definition as Swagger Spec 2.0's info Object
securityDefinitions You can put your security definitions here, see more details below
templatePath The path of a handlebars template file, see more details below.
outputPath The path of the generated static document, not existed parent directories will be created. If you don't want to generate a static document, just don't set it.
outputFormats The format types of the generated swagger spec. Valid values are json, yaml or both json,yaml. The json format is default.
swaggerDirectory The directory of generated swagger.json file. If null, no swagger.json will be generated.
swaggerFileName The filename of generated filename.json file. If null, swagger.json will be generated.
swaggerApiReader If not null, the value should be a full name of the class implementing com.github.kongchen.swagger.docgen.reader.ClassSwaggerReader. This allows you to flexibly implement/override the reader's implementation. com.github.kongchen.swagger.docgen.reader.SwaggerReader can be used to strictly use the official Swagger reader in order to generate the exact same output as Swagger''s runtime generation (with all its bugs). Default is com.github.kongchen.swagger.docgen.reader.JaxrsReader.
attachSwaggerArtifact If enabled, the generated swagger.json file will be attached as a maven artifact. The swaggerDirectory's name will be used as an artifact classifier. Default is false.
modelSubstitute The model substitute file's path, see more details below
typesToSkip Nodes of class names to explicitly skip during parameter processing. More details below
apiModelPropertyAccessExclusions Allows the exclusion of specified @ApiModelProperty fields. This can be used to hide certain model properties from the swagger spec. More details below
jsonExampleValues If true, all example values in @ApiModelProperty will be handled as json raw values. This is useful for creating valid examples in the generated json for all property types, including non-string ones.
modelConverters List of custom implementations of io.swagger.converter.ModelConverter that should be used when generating the swagger files.
swaggerExtensions List of custom implementations of io.swagger.jaxrs.ext.SwaggerExtension that should be used when generating the swagger files.
enabledObjectMapperFeatures List of ConfigFeature enums that are supported by ObjectMapper.configure - the feature is set to true. https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#features) here, see more details below
disabledObjectMapperFeatures List of ConfigFeature enums that are supported by ObjectMapper.configure - the feature is set to false. https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#features) here, see more details below
operationIdFormat Format of operationId used in Swagger spec. For historical reasons default is Java method name. Since 3.1.8, for new APIs suggested format is: {{className}}_{{methodName}}_{{httpMethod}}. {{packageName}} token is also supported.
externalDocs URL Reference to external documentation
responseMessageOverrides Default response message overrides of type @ApiResponse. Example: <responseMessageOverrides><responseMessageOverride><code>401</code><message>Unauthenticated - could not authenticate the user.</message></responseMessageOverride></responseMessageOverrides>

If you'd like to generate a template-driven static document, such as markdown or HTML documentation, you'll need to specify a handlebars template file in templatePath. The value for templatePath supports 2 kinds of path:

  1. Resource in classpath. You should specify a resource path with a classpath: prefix. e.g:

    1. classpath:/markdown.hbs
    2. classpath:/templates/hello.html
  2. Local file's absolute path. e.g:

    1. ${basedir}/src/main/resources/markdown.hbs
    2. ${basedir}/src/main/resources/template/hello.html

There's a standalone project for the template files, fetch them and customize it for your own project.

There are 3 types of security definitions according to Swagger Spec: basic, apiKey and oauth2.

You can define multi definitions here, but you should fully follow the spec.

You can define a basic definition like this:

<securityDefinition>
    <name>MybasicAuth</name>
    <type>basic</type>
</securityDefinition>

or define several definitions in a json file and specify the json path like this:

<securityDefinition>
    <json>/securityDefinition.json</json>
</securityDefinition>

The file will be read by getClass().getResourceAsStream, so please note the path you configured.

Alternatively, specify the absolute file path to the json definition file:

<securityDefinition>
    <jsonPath>${basedir}/securityDefinition.json</jsonPath>
</securityDefinition>

The securityDefinition.json file should also follow the spec, one sample file like this:

{
  "api_key": {
    "type": "apiKey",
    "name": "api_key",
    "in": "header"
  },
  "petstore_auth": {
    "type": "oauth2",
    "authorizationUrl": "http://swagger.io/api/oauth/dialog",
    "flow": "implicit",
    "scopes": {
      "write:pets": "modify pets in your account",
      "read:pets": "read your pets"
    }
  }
}

Throughout the course of working with Swagger, you may find that you need to substitute non-primitive objects for primitive objects. This is called model substitution, and it is supported by swagger-maven-plugin. In order to configure model substitution, you'll need to create a model substitute file. This file is a simple text file containing n lines, where each line tells swagger-maven-plugin to substitutes a model class with the supplied substitute. These two classes should be separated by a colon (:).

Sample model substitution

com.foo.bar.PetName : java.lang.String

The above model substitution configuration would tell the plugin to substitute com.foo.bar.PetName with java.lang.String. As a result, the generated swagger.json would look like this ...

 "definitions" : {
    "Pet" : {
      "properties" : {
        ...
        "petName" : {
          "type" : "string"
        }
        ...
      }
    }

... instead of like this:

 "definitions" : {
    "Pet" : {
      "properties" : {
        ...
        "petName" : {
          "$ref" : "#/definitions/PetName"
        }
        ...
      }
    }

The model substitution file will be read by getClass().getResourceAsStream, so please note the path you configured.

You can instruct swagger-maven-plugin to skip processing the parameters of certain types by adding the following to your pom.xml:

<typesToSkip>
  <typeToSkip>com.foobar.skipper.SkipThisClassPlease</typeToSkip>
  <typeToSkip>com.foobar.skipper.AlsoSkipThisClassPlease</typeToSkip>
</typesToSkip>

This requires at least swagger-maven-plugin version 3.1.1-SNAPSHOT.

If you'd like to exclude certain @ApiModelPropertys based on their access values, you may do so by adding the following as a child node of apiSource in your pom.xml:

<apiModelPropertyAccessExclusions>
    <apiModelPropertyAccessExclusion>secret-property</apiModelPropertyAccessExclusion>
</apiModelPropertyAccessExclusions>

The above setting would prevent internalThing from appearing in the swagger spec output, given this annotated model:

...
    @ApiModelProperty(name = "internalThing", access = "secret-property")
    public String getInternalThing() {
        return internalThing;
    }
...

Note: In order to use apiModelPropertyAccessExclusions, you must specify both the name and access fields of the property you wish to exclude. Additionally, apiModelPropertyAccessExclusions requires at least swagger-maven-plugin version 3.1.1-SNAPSHOT.

Defining common Swagger parameters with JAX-RS annotations

When defining the Swagger API with JAX-RS, it is possible to specify common parameters by defining an @Api class that only contains fields annotated with JAX-RS parameter annotations. Note that this class should not contain any @Path or HTTP method annotation in order to consider it as a declaration of common parameters. When a common parameter is specified in another JAX-RS resource class, the parameter will have a reference to the common parameter.

The result of having common parameters and parameter references can be seen in the test file swagger-common-parameters.json. The @Api class used to generate this example can be seen in the test file JaxrsReaderTest.java.

Install/Deploy swagger.json

You can instruct swagger-maven-plugin to deploy the generated swagger.json by adding the following to your pom.xml:

<swaggerDirectory>${project.build.directory}/swagger-ui</swaggerDirectory>
<attachSwaggerArtifact>true</attachSwaggerArtifact>

or custom.json by adding the following to your pom.xml:

<swaggerDirectory>${project.build.directory}/swagger-ui</swaggerDirectory>
<swaggerFileName>custom</swaggerFileName>
<attachSwaggerArtifact>true</attachSwaggerArtifact>

The above setting attaches the generated file to Maven for install/deploy purpose with swagger-uias classifier and json as type

Enables or disables the static Json.mapper config, by setting the feature of a known enum to true or false respectively.

N.B. Inner class fully qualified domain names are using $

<configuration>
...
   <enabledObjectMapperFeatures>
       <feature>com.fasterxml.jackson.databind.SerializationFeature.WRITE_ENUMS_USING_TO_STRING</feature>
       <feature>com.fasterxml.jackson.core.JsonParser$Feature.ALLOW_NUMERIC_LEADING_ZEROS</feature>
   </enabledObjectMapperFeatures>
...
    <disabledObjectMapperFeatures>
        <feature>com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS</feature>
    </disabledObjectMapperFeatures>
</configuration>

Example

There's a sample here, just fork it and have a try.

A Sample Configuration

<project>
...
<build>
<plugins>
<plugin>
    <groupId>com.github.kongchen</groupId>
    <artifactId>swagger-maven-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <apiSources>
            <apiSource>
	            <springmvc>true</springmvc>
                <locations>
                    <location>com.wordnik.swagger.sample</location>
                </locations>
                <schemes>
                    <scheme>http</scheme>
                    <scheme>https</scheme>
                </schemes>
                <host>www.example.com:8080</host>
                <basePath>/api</basePath>
                <info>
                    <title>Swagger Maven Plugin Sample</title>
                    <version>v1</version>
                    <!-- use markdown here because I'm using markdown for output,
                    if you need to use html or other markup language, you need to use your target language,
                     and note escape your description for xml -->
                    <description>
                        This is a sample.
                    </description>
                    <termsOfService>
                        http://www.github.com/kongchen/swagger-maven-plugin
                    </termsOfService>
                    <contact>
                        <email>[email protected]</email>
                        <name>Kong Chen</name>
                        <url>http://kongch.com</url>
                    </contact>
                    <license>
                        <url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
                        <name>Apache 2.0</name>
                    </license>
                </info>
                <securityDefinitions>
                    <securityDefinition>
                        <name>basicAuth</name>
                        <type>basic</type>
                    </securityDefinition>
                    <securityDefinition>
                        <json>/securityDefinition.json</json>
                    </securityDefinition>
                </securityDefinitions>
                <responseMessageOverrides>
                    <responseMessageOverride>
                        <code>401</code>
                        <message>Unauthenticated - could not authenticate the user.</message>
                    </responseMessageOverride>
                    <responseMessageOverride>
                        <code>403</code>
                        <message>Forbidden - the user does not have the required permissions to execute this request.</message>
                    </responseMessageOverride>
                </responseMessageOverrides>

                <!-- Support classpath or file absolute path here.
                1) classpath e.g: "classpath:/markdown.hbs", "classpath:/templates/hello.html"
                2) file e.g: "${basedir}/src/main/resources/markdown.hbs",
                    "${basedir}/src/main/resources/template/hello.html" -->
                <templatePath>${basedir}/src/test/resources/strapdown.html.hbs</templatePath>
                <outputPath>${basedir}/generated/document.html</outputPath>
                <swaggerDirectory>${basedir}/generated/swagger-ui</swaggerDirectory>
                <swaggerApiReader>com.wordnik.swagger.jaxrs.reader.DefaultJaxrsApiReader</swaggerApiReader>
                <attachSwaggerArtifact>true</attachSwaggerArtifact>
                <modelConverters>io.swagger.validator.BeanValidator</modelConverters>
                <swaggerExtensions>
                    <swaggerExtension>com.example.VendorExtension</swaggerExtension>
                </swaggerExtensions>
                <enabledObjectMapperFeatures>
                    <feature>com.fasterxml.jackson.databind.SerializationFeature.WRITE_ENUMS_USING_TO_STRING</feature>
                    <feature>com.fasterxml.jackson.core.JsonParser$Feature.ALLOW_NUMERIC_LEADING_ZEROS</feature>
                </enabledObjectMapperFeatures>
                <disabledObjectMapperFeatures>
                    <feature>com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS</feature>
                </disabledObjectMapperFeatures>
                <operationIdFormat>{{className}}_{{methodName}}_{{httpMethod}}</operationIdFormat>
                <externalDocs>
                    <description>Example external docs</description>
                    <url>https://example.com/docs</url>
                </externalDocs>
            </apiSource>
        </apiSources>
    </configuration>
    <executions>
        <execution>
            <phase>compile</phase>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <!-- Adding dependency to swagger-hibernate-validations to enable the BeanValidator as a custom
             model converter -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-hibernate-validations</artifactId>
            <version>1.5.6</version>
        </dependency>
    </dependencies>
</plugin>
...
</plugins>
</build>
</project>

FAQ

1. SNAPSHOT Version

SNAPSHOT versions are available for verifying issues and new features. If you would like to try to verify the fixed issues or the new added features, you may need to add a pluginRepository node in your pom.xml:

<pluginRepositories>
  <pluginRepository>
    <id>sonatype-snapshot</id>
    <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
    <releases>
      <enabled>false</enabled>
    </releases>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </pluginRepository>
</pluginRepositories>

2. Dependency conflicts

If you have package dependency conflict issues, such as jackson, joda-time, or jsr311-api. Run

mvn dependency:tree

to check which package introduces the one conflicts with yours, and then you can use <exclusion> configuration in pom.xml to exclude it.

Here's an example:

To exclude javax.ws.rs:jsr311-api:jar:1.1.1:compile from swagger-jaxrs_2.10:

<dependency>
    <groupId>com.wordnik</groupId>
    <artifactId>swagger-jaxrs_2.10</artifactId>
    <version>1.3.2</version>
    <exclusions>
        <exclusion>
            <groupId>javax.ws.rs</groupId>
            <artifactId>jsr311-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

3. Building from source

To build from source and run tests, you should:

mvn install

swagger-maven-plugin's People

Contributors

a-n710 avatar albx79 avatar alexelin avatar artkoshelev avatar bellorap avatar brettporter avatar cjelger avatar dangllucas avatar danieleorler avatar dantran avatar farbauti89 avatar fuzzybutter avatar haywhisksoftware avatar jjank avatar jonesgeek avatar kongchen avatar krasa avatar ldez avatar mortias avatar packleader avatar peteryhwong avatar postremus avatar rakk avatar sudohippie avatar tedleman avatar tjuchniewicz avatar vaclavchalupa avatar vbauer avatar viktorgunnarson avatar who avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swagger-maven-plugin's Issues

goal fails when outputPath is a directory that does not exist yet

If the directory described by outputPath does not exist, the goal fails. The example application has the "generated" directory checked in, that's why it works well there.
I've forked swagger-maven-example and committed the outputPath to how I'd like to use it ( [email protected]:bcollison-vrv/swagger-maven-example.git )

I've also forked swagger-maven-plugin ( [email protected]:bcollison-vrv/swagger-maven-plugin.git ) to provide this functionality, please consider my pull request

@JsonIgnore is not honored

I have tried @JsonIgnore on fields as well as getters and setters and it is never honored. The generated JSON still includes those fields as part of the model.

We have lots of fields in the model that are not appropriate to send to the client (either for security reasons or just because they are irrelevant for the client), and we need to hide them.

Swagger-core uses @JsonIgnore for this purpose, so I think this plugin should operate in the same manner.

2.1 Release request

I would like to use the changes in 2.1 in my project but to check the changes into my project trunk requires a released version. Can you please release a version 2.1 within one week? Let me know how I can help. Thanks! Dave

Plugin Missing Log4j.xml File

Hi - I've run into a problem where swagger-maven-plugin is searching my classpath for a log4j xml file, as there isn't one included in the plugin jar. This blows up for me because it finds a scala specific logging configuration for another jar, and the scala libraries aren't loaded by maven.

Can you add a simple log4j.xml file to the project? Here's a hello-world sample which should work. When I manually add this to the jar file myself, it solves the problem. I wasn't able to find a workaround for this, otherwise I wouldn't bother.

Thanks for all of the work on this plugin!

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
</log4j:configuration>

MustacheException: Failed to read

Hello,

with any template I get the following Exception:

...
[DEBUG] [com.github.kongchen.swagger.docgen.mavenplugin.ApiSource@38e53797]
log4j:WARN No appenders could be found for logger (org.reflections.Reflections).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
[INFO] Detect Resource:com.encoway.catalog.web.ArticlesController
[INFO] Writing doc to E:\GIT\catalog-service\catalog-service-rest/target/generated/api-doc.html...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.802s
[INFO] Finished at: Fri Jul 04 12:48:23 CEST 2014
[INFO] Final Memory: 15M/438M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.github.kongchen:swagger-maven-plugin:2.2:generate (default-cli) on project catalog-service-rest: Failed to read: Stream closed -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal com.github.kongchen:swagger-maven-plugin:2.2:generate (default-cli) on project catalog-service-rest: Failed to read
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoExecutionException: Failed to read
    at com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo.execute(ApiDocumentMojo.java:68)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
Caused by: com.github.mustachejava.MustacheException: Failed to read
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:235)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:115)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:39)
    at com.github.mustachejava.DefaultMustacheFactory.compile(DefaultMustacheFactory.java:195)
    at com.github.mustachejava.DefaultMustacheFactory.compile(DefaultMustacheFactory.java:190)
    at com.github.kongchen.swagger.docgen.AbstractDocumentSource.toDocuments(AbstractDocumentSource.java:258)
    at com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo.execute(ApiDocumentMojo.java:61)
    ... 21 more
Caused by: java.io.IOException: Stream closed
    at java.io.BufferedReader.ensureOpen(BufferedReader.java:115)
    at java.io.BufferedReader.read(BufferedReader.java:172)
    at com.github.mustachejava.MustacheParser.compile(MustacheParser.java:66)
    ... 123 more
[ERROR] 
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

My plugin configuration:

...
                <plugin>
                    <groupId>com.github.kongchen</groupId>
                    <artifactId>swagger-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <apiSources>
                            <apiSource>
                                <locations>com.encoway.catalog.web.ArticlesController</locations>
                                <apiVersion>${project.version}</apiVersion>
                                <basePath>http://localhost:8080/catalog-service</basePath>
                                <!-- <mustacheFileRoot>${basedir}/src/main/resources/META-INF/api-doc-templates/</mustacheFileRoot> -->
                                <outputTemplate>${basedir}/src/main/resources/META-INF/api-doc-templates/html.mustache</outputTemplate>
                                <outputPath>${basedir}/target/generated/api-doc.html</outputPath>
                                <!--swaggerDirectory>generated/apidocs</swaggerDirectory -->
                                <!--swaggerUIDocBasePath>http://www.example.com/restapi/doc</swaggerUIDocBasePath -->
                                <!--useOutputFlatStructure>false</useOutputFlatStructure -->
                            </apiSource>
                        </apiSources>
                    </configuration>
                    <executions>
                        <execution>
                            <phase>compile</phase>
                            <goals>
                                <goal>generate</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
...

Does anybody else had this problem and found a solution?
Thanks in advance.

Florian

JAX RS @Path with muti segments

I have a service with this path: /companies/tgss
The generation with swagger-maven-plugin runs for the strapdown.html file, but not for services.json. In service.json the path is changed by "/companies_tgss.{format}"

Feature Request: Sort methods, dataTypes, and dataType parameters

Would like html output to sort

  • methods by name, then HTTP method
  • dataTypes - as a whole, with request/response combined
  • dataType parameters

A simple, naive solution involves

  • OutputTemplate.createMustacheDocument:
  • -> sorting swaggerDoc.getApis prior to adding to the mustacheDocument
  • -> sorting swagger api operations before adding adding to the mustacheDocument
  • MustacheDataType: sorting items in getItems or in the ctor and setItems

Very handy plugin btw, thank you for your effort. I am using it in mule - only way I have found to present this type of documentation in that environment.

Parameter name problem in markdown

In Scala I have a bunch of method parameters annotated like this:

def method_name(@ApiParam(name = "Environment", value = "Description", required = true) env: String = null) { ... }

Via the swagger-maven-plugin I generated documentation using strapdown.html.mustache. In the generated file, in the "Parameters" table, in the "Parameter" column I am expecting the name of the parameter (i.e. Environment) but the data type is displayed.

model and error sections not getting generated

I am using swagger-maven-plugin and have annotated my api as described in the tutorial. I noticed that the model and errors subsection of the output json doc are not getting generated. 'RevokeAccountRequest' is my model which I have annotated properly.

Example annotation:

@PUT
@Path("/customer/{customerId}/revoke")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Revoke a customer account", notes = "More notes about this method")
@ApiImplicitParams(@ApiImplicitParam(name = "body", value = "Revoke date", required = true, dataType = "RevokeAccountRequest", paramType = "body"))
@ApiResponses(value = {
  @ApiResponse(code = 400, message = "One or more required input parameter missing."),
  @ApiResponse(code = 401, message = "Authentication failure."),
  @ApiResponse(code = 403, message = "Authorization failure."),
  @ApiResponse(code = 404, message = "SecretId not found."),
  @ApiResponse(code = 500, message = "Server Error."),
})  

notes doesn't seem to work

My api proeprty is like so:

@ApiModelProperty(value = "Some Description", required = true, notes = "Some Notes",)

My wiki.markdown is as follows:

h1. Data Types
{{#dataTypes}}
{anchor:{{name}}}
h3. {{name}}
|| ||*type*||*required*||*schema*||*constraints*||
{{#items}}
|*{{name}}*|{{type}}|{{#required}}required{{/required}}{{^required}}optional{{/required}}|{{#description}}{{{description}}}{{/description}}{{^description}}-{{/description}}|{{#notes}}{{{notes}}}{{/notes}}{{^notes}}-{{/notes}}|
{{/items}}
{{/dataTypes}}

The notes column in the output gets "Some Description" rather than "Some Notes"

Using Enum as ApiParam throws a NPE

If I try to use the maven plugin when an Api endpoint has an Enum parameter the following stack trace is produced:

[ERROR] Failed to execute goal com.github.kongchen:swagger-maven-plugin:1.1.3-SNAPSHOT:generate (gen-api-docs) on project MAMService: null: MojoExecutionException: NullPointerException -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal com.github.kongchen:swagger-maven-plugin:1.1.3-SNAPSHOT:generate (gen-api-docs) on project MAMService: null
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoExecutionException
    at com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo.execute(ApiDocumentMojo.java:65)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
Caused by: java.lang.NullPointerException
    at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.addDateType(OutputTemplate.java:52)
    at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.createMustacheDocument(OutputTemplate.java:107)
    at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.feedSource(OutputTemplate.java:155)
    at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.<init>(OutputTemplate.java:30)
    at com.github.kongchen.swagger.docgen.AbstractDocumentSource.prepareMustacheTemplate(AbstractDocumentSource.java:196)
    at com.github.kongchen.swagger.docgen.AbstractDocumentSource.toDocuments(AbstractDocumentSource.java:202)
    at com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo.execute(ApiDocumentMojo.java:58)
    ... 21 more

Replacing the Enum with a concrete class works as expected

ClassCastException for AnyAllowableValues -> AllowableRangeValues

full trace:
[ERROR] Failed to execute goal com.github.kongchen:swagger-maven-plugin:2.0-SNAPSHOT:generate (default) on project gaia-webapp: com.wordnik.swagger.model.AnyAllowableValues$ cannot be cast to com.wordnik.swagger.model.AllowableRangeValues -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal com.github.kongchen:swagger-maven-plugin:2.0-SNAPSHOT:generate (default) on project gaia-webapp: com.wordnik.swagger.model.AnyAllowableValues$ cannot be cast to com.wordnik.swagger.model.AllowableRangeValues
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.MojoExecutor.executeForkedExecutions(MojoExecutor.java:365)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:199)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoExecutionException: com.wordnik.swagger.model.AnyAllowableValues$ cannot be cast to com.wordnik.swagger.model.AllowableRangeValues
at com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo.execute(ApiDocumentMojo.java:71)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
... 23 more
Caused by: java.lang.ClassCastException: com.wordnik.swagger.model.AnyAllowableValues$ cannot be cast to com.wordnik.swagger.model.AllowableRangeValues
at com.github.kongchen.swagger.docgen.mustache.MustacheParameter.allowableValuesToString(MustacheParameter.java:58)
at com.github.kongchen.swagger.docgen.mustache.MustacheParameter.(MustacheParameter.java:40)
at com.github.kongchen.swagger.docgen.mustache.MustacheDocument.analyzeParameter(MustacheDocument.java:138)
at com.github.kongchen.swagger.docgen.mustache.MustacheDocument.toParameterTypeMap(MustacheDocument.java:124)
at com.github.kongchen.swagger.docgen.mustache.MustacheDocument.analyzeParameters(MustacheDocument.java:111)
at com.github.kongchen.swagger.docgen.mustache.MustacheOperation.(MustacheOperation.java:58)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.createMustacheDocument(OutputTemplate.java:99)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.feedSource(OutputTemplate.java:158)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.(OutputTemplate.java:29)
at com.github.kongchen.swagger.docgen.AbstractDocumentSource.prepareMustacheTemplate(AbstractDocumentSource.java:218)
at com.github.kongchen.swagger.docgen.AbstractDocumentSource.toDocuments(AbstractDocumentSource.java:224)
at com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo.execute(ApiDocumentMojo.java:64)
... 25 more

1.3.2 of swagger is used. Let me know if you need more details.

No way to output 'Index' plus additional HTML files

Right now the implementation of this plugin seems to generate a single HTML file and there does not seem to be a way to cause the plugin to generate multiple files. Our API space is very very large and having all of it in a single HTML file is quite unwieldy.

It would even be better if it were possible to direct the HTML page to use the generate swagger .json output files.

Maybe I missed it - does this ability to cause multiple output files exist? or is it not something that this currently supports.

Unable to load class void / Failed to read

Hello,

I just discovered swagger and swagger maven plugin and wanted immediately integrate it into my build.

I am getting this

[DEBUG] Configuring mojo com.github.kongchen:swagger-maven-plugin:1.1.1:generate from plugin realm ClassRealm[plugin>com.github.kongchen:swagger-maven
-plugin:1.1.1, parent: sun.misc.Launcher$AppClassLoader@425224ee]
[DEBUG] Configuring mojo 'com.github.kongchen:swagger-maven-plugin:1.1.1:generate' with include-project-dependencies configurator -->
DEBUG locations = si.najdi.web.rest.services
DEBUG apiVersion = v1
DEBUG basePath = http://www.najdi.si/rest
DEBUG outputTemplate = https://github.com/kongchen/api-doc-template/blob/master/v1.1/wiki-new.mustache
DEBUG outputPath = src/site/generated-api-doc/najdi-rest.html
DEBUG withFormatSuffix = false
DEBUG apiSources = [com.github.kongchen.swagger.docgen.mavenplugin.ApiSource@436cbab3]
[DEBUG] -- end configuration --
...
[16:41:53] INFO [org.reflections.Reflections]: Reflections took 84 ms to scan 1 urls, producing 16 keys and 29 values
[16:41:53] ERROR [com.wordnik.swagger.core.util.TypeUtil$]: Unable to load class void
[INFO] Detect Resource:si.najdi.web.rest.services.BicikeljResource
[INFO] Writing doc to src/site/generated-api-doc/najdi-rest.html...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

[ERROR] Failed to execute goal com.github.kongchen:swagger-maven-plugin:1.1.1:generate (default) on project najdi-web: Failed to read -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal com.github.kongchen:swagger-maven-plugin:1.1.1:generate (default) on pr
oject najdi-web: Failed to read
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:213)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoFailureException: Failed to read
at com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo.execute(ApiDocumentMojo.java:58)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
... 19 more

There is an empty file generated najdi-rest.html. What could be the cause?

Am I understanding correctly, that just the documentation will be generated, no active server is needed (I have no servlet defined, just following the example at https://github.com/kongchen/swagger-maven-plugin).

Best regards,
borut

Infinite loop when generating template

I got an infinite loop generating the Swagger template for my project.

After some time i managed to isolate the issue. If the model contains a circular dependency between classes OuputTemplate.addDataType adds the same classes over and over.

Simple example:

public class Parent {
public Child getChild() {
return new Child();
}
}

public class Child extends Parent {}

Using either the Parent or Child class as responseClass in a service will cause the problem to occur.

Partial stacktrace:

Exception in thread "main" java.lang.StackOverflowError
at java.util.regex.Pattern$Branch.match(Pattern.java:4502)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4556)
at java.util.regex.Pattern$Begin.match(Pattern.java:3472)
at java.util.regex.Matcher.search(Matcher.java:1199)
at java.util.regex.Matcher.find(Matcher.java:592)
at com.github.kongchen.swagger.docgen.TypeUtils.getTrueType(TypeUtils.java:31)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.addDateType(OutputTemplate.java:50)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.addDateType(OutputTemplate.java:54)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.addDateType(OutputTemplate.java:54)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.addDateType(OutputTemplate.java:54)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.addDateType(OutputTemplate.java:54)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.addDateType(OutputTemplate.java:54)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.addDateType(OutputTemplate.java:54)
at com.github.kongchen.swagger.docgen.mustache.OutputTemplate.addDateType(OutputTemplate.java:54)

responseClass is always void

The following Java code:

    // REST method:
    @ApiOperation(
            value = "Get users",
            response = Users.class,
            httpMethod = "GET"
    )
    public Users getUsers( .. ) { .. }

    // Users class:
    @ApiModel(
            value = "Users",
            description = "Registered users"
    )
    public class Users { .. }

generates this meta.json:

    {
        "operations" : [ {
          "httpMethod" : "GET",
          "summary" : "Get users",
          "responseClass" : "void",
          "nickname" : "getUsers"
        } ]
    }

and in the compile logs I see:

14/01/28 16:15:28 INFO reflections.Reflections: Reflections took 65 ms to scan 1 urls, producing 7 keys and 7 values 
14/01/28 16:15:28 ERROR util.TypeUtil$: Unable to load class void

I've tried using response = String.class and I get the same result. It appears that it isn't reading any classes and uses Void.class by default.

I am using springframework 3.1.3.RELEASE, swagger-jaxrs_2.10 1.3., swagger-annotations 1.3.1, swagger-maven-plugin 1.1.1.

Overriding Model

Is there any way can override model for swagger-maven-plugin ?

for example:

"Date": {
"id": "Date",
"properties": {
"time": {
"type": "long"
},
"minutes": {
"type": "int"
},
"seconds": {
"type": "int"
},
"hours": {
"type": "int"
....}

becomes

"Date": {
"id": "Date",
"properties": {
"value": {
"required": true,
"description": "Date in ISO-8601 format",
"notes": "Add any notes you like here",
"type": "string"
}
}
}

the original solution for override mode in swagger core seems not work for
swagger-maven-plugin (?)

any idea?

Possibility of removing the '.json' extension for the generated files for swagger-ui compatibility

Hi guys,

I get the json files generated, as expected:

  • service.json (including paths for other services definitions, i.e. /persons, /companies)
  • the services definitions themselves (persons.json, companies.json, etc.)

I can show the list of services from swagger-ui. But in order to find the individual services definitions I must:
a) delete the '.json' extension for every file, or
b) add .json to every path inside "apis" element in resources.json:
"apis" : [ {
"path" : "/regions.json",

Is there any way so that I don't need any further modification, so that the paths inside resources.json matches the names of the individual resources definition? Avoiding the addition of *.json extension to every individual service definition would do it...

Generated HTML does not contain HTML tag

Sorry for a simple basic question. I followed the swagger-maven-example and tried to generate HTML doc for my api. However, the generated HTML has no surrounding HTML tags like:

<!DOCTYPE html>
<html>
<title>API Document</title>
<xmp theme="united" style="display:none;">
....
</xmp>
<script src="http://strapdownjs.com/v/0.2/strapdown.js"></script>
</html>

What am I doing wrong?

Thanks so much.

A required class was missing javax/validation/Validator

If I have a validator injected into my REST api:

    @Resource
    Validator validator;

I hit

Failed to execute goal com.github.kongchen:swagger-maven-plugin:2.0:generate (default) on project my-war: Execution default of goal com.github.kongchen:swagger-maven-plugin:2.0:generate failed: A required class was missing while executing com.github.kongchen:swagger-maven-plugin:2.0:generate: Ljavax/validation/Validator;
-----------------------------------------------------
realm =    plugin>com.github.kongchen:swagger-maven-plugin:2.0

I needed to add the validator with compile scope but this is provided by the AppServer so I don't need or want to bundle this dependency.

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.3.1.Final</version>
            <scope>compile</scope>
        </dependency>

notes for the ApiModelProperty are ignored.

I am using

com.wordnik
swagger-jaxrs_2.10
1.3.2
and
com.github.kongchen
swagger-maven-plugin
2.0
I have a class that is annotated like this...

@apimodel(value = "MyDo information")
@XmlRootElement
public class MyDo extends AbstractDomainObject {

@ApiModelProperty(required = true, notes = "the first key")
private String key1;
@ApiModelProperty(required = true, notes = "the second key")
private String key2;
@ApiModelProperty(required = true, value = "This is really cool", notes = "key3", allowableValues = "this, that")
private String key3;

/* stuff not needed for swagger here */
}

The generated json is
"MyDo" : {
"id" : "MyDo",
"required" : [ "key3", "key2", "key1" ],
"properties" : {
"key3" : {
"type" : "string",
"description" : "This is really cool",
"enum" : [ "this", " that" ]
},
"key2" : {
"type" : "string"
},
"key1" : {
"type" : "string"
}
}
}

The "notes" are not specified in the above .json Also when I try to display them using the templates provided the {{{notes}}} values and the {{{description}}} are both the description

What does basePath on an @Api annotation do?

Hi, I love your plugin, and it almost works for me. The problem is that I have several APIs on my server with different base paths. So, I am trying to use something like this:

@path("/")
@Api(basePath="/schema", value = "/schema", description = "Schema resource")
public class SchemaResource {
...
@get
@path("table/{tablename}/{id}")
public SchemaRecord getTableRow (
@ApiParam(TABLE_NAME_PARAM) @PathParam("tablename") String tablename,
@ApiParam(ID_PARAM) @PathParam("id") long id) {
...
}

}

I have "/ws" prefixed to all my calls (through the basePath in the POM). I need to have the URI be like: /ws/schema/table/MY_TABLE_NAME/1234 and would have expected basePath on the @Api annotation to make that happen, but it does not. Am I misunderstanding what basePath on @Api is supposed to do? Thanks!

Gary Bisaga

Data Model Property with Hidden property

Hi,
Seems like data model property with hidden property = true is still being displayed/included in the generated Data Type section?

e.g. @ApiModelProperty(value = "some property", required = true, hidden = true)

or have I misinterpreted the use of hidden?

Thanks.

Configured basePath not used in output.

I'm using this plugin configuration to generate the swagger spec for my api. But even if the basePath is configured, it is not outputted in the service.json. Because of that, the lastest swagger-ui won't be able to resolve the individual resource documentations.

I've manually added the basePath in the generated service.json and with that all works well.

<plugin>
    <groupId>com.github.kongchen</groupId>
    <artifactId>swagger-maven-plugin</artifactId>
    <version>2.0</version>
    <configuration>
        <apiSources>
            <apiSource>
                <locations>com.roche.research.mwa.resources</locations>
                <apiVersion>v1</apiVersion>
                <basePath>http://localhost:8080/restapi</basePath>
                <outputTemplate>${basedir}/src/main/resources/markdown.mustache</outputTemplate>
                <outputPath>${basedir}}/target/restapi/strapdown.html</outputPath>
                <swaggerDirectory>${basedir}/target/restapi</swaggerDirectory>
            </apiSource>
    </apiSources>
</configuration>

JSON Output for swagger-ui

Hi there, thanks for the great plugin.

Generation works fine for me, but an different output would be useful.
Do you think it's possible to generate the json format that can be used by swagger-ui to render the documentation?
With some hints I would try to contribute and test this feature.

Regards

Mustache html output not generating properly

The mustache html output is not formatting correctly. The class attribute is only included in the first resource. The div id's are are all set to "accordion0api" The "index" attribute does not seem to be set correctly.

<h3>Resources</h3>
<h4>/package</h4>
<div id="accordion0api" class="ui-accordion ui-widget ui-helper-reset" role="tablist">

<h4>/cart</h4>
<div id="accordion0api">

I am using:
 <dependency>
                <groupId>com.wordnik</groupId>
                <artifactId>swagger-annotations</artifactId>
                <version>1.3.2</version>
</dependency>
        <plugin>
            <groupId>com.github.kongchen</groupId>
            <artifactId>swagger-maven-plugin</artifactId>
            <!--<version>2.0-SNAPSHOT</version>-->
            <version>2.0</version>
            <configuration>
                <apiSources>
                    <apiSource>
                        <!--<locations>com.foo.bar.apis;com.foo.bar.apis.internal.Resource</locations>-->
                        <locations>com.bestbuy.activateddevices.beagle.resources</locations>
                            <!--;com.bestbuy.activateddevices.domain.accountline</locations>-->
                        <apiVersion>v1</apiVersion>
                        <basePath>/beagle</basePath>
                        <outputTemplate>
                            https://raw.github.com/kongchen/api-doc-template/master/v2.0/html.mustache
                        </outputTemplate>
                        <!--https://raw.github.com/kongchen/api-doc-template/master/v2.0/markdown.mustache
                            https://raw.github.com/kongchen/api-doc-template/master/v2.0/html.mustache

                        -->
                        <outputPath>generated/beagle-api.html</outputPath>
                        <swaggerDirectory>generated/apidocs</swaggerDirectory>
                        <!--useOutputFlatStructure>false</useOutputFlatStructure-->
                        <!--mustacheFileRoot>${basedir}/src/main/resources/</mustacheFileRoot-->
                    </apiSource>
                </apiSources>
            </configuration>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

"Access" Missing on MustacheItem

Hi - With the migration to 2.0 (1.3.2 swagger-core), the access field is missing from models. It looks like MustacheItem no longer populates that field. You can see it removed in this change: 0ccfaf4

Is that by design? If so, what is the preferred way to get the "access" attribute?

Thanks!

Internal types supporting

Hello. Thank for the great work, again!

The issue is related to the generating data types specs for the complex model object.
For eg:

public class Customer implements Entity<Integer> {
private String name;
private String surname;
private Integer id;
private Address address;
private List<Email> emails;

/**
 * {@inheritDoc}
 */
@XmlElement(name = "id")
@ApiProperty(required = true, notes = "Customer's identifier")
@Override
public Integer getId() {
    return id;
}

/**
 * {@inheritDoc}
 */
@Override
public void setId(Integer id) {
    this.id = id;
}

@XmlElement(name = "surname")
@ApiProperty(required = true, notes = "Customer's surname")
public String getSurname() {
    return surname;
}

public void setSurname(String surname) {
    this.surname = surname;
}

@XmlElement(name = "name")
@ApiProperty(required = true, notes = "Customer's name")
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@XmlElement(required = false, name = "email")
@ApiProperty(notes = "The list of customer emails", required = false,
        dataType = "Email")
public List<Email> getEmails() {
    return emails;
}

public void setEmails(List<Email> emails) {
    this.emails = emails;
}

@XmlElement(name = "address", required = false)
@ApiProperty(required = false, notes = "Customer's address", 
        dataType = "Address")
public Address getAddress() {
    return address;
}

public void setAddress(Address address) {
    this.address = address;
}
}

public class Email implements Entity<Integer> {
private String email;
private Boolean byDefault;
private Integer id;

/**
 * {@inheritDoc}
 */
@XmlElement(name = "id")
@ApiProperty(notes = "Email identifier")
@Override
public Integer getId() {
    return id;
}

/**
 * {@inheritDoc}
 */
@Override
public void setId(Integer id) {
    this.id = id;
}

@XmlElement(name = "address")
@ApiProperty(notes = "Email address")
public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

@XmlElement(name = "default", required = false)
    @ApiProperty(notes = "The flag shows if this email is a default email",
        required = false)
public Boolean getByDefault() {
    return byDefault;
}

public void setByDefault(Boolean byDefault) {
    this.byDefault = byDefault;
}
}

public class Address implements Entity<Integer> {
private Integer id;
private String location;
private Long zipCode;

/**
 * {@inheritDoc}
 */
@XmlElement(name = "id")
@ApiProperty(notes = "Address' indentifier")
@Override
public Integer getId() {
    return id;
}

/**
 * {@inheritDoc}
 */
@Override
public void setId(Integer id) {
    this.id = id;
}

@XmlElement(name = "zip", required = false)
@ApiProperty(notes = "The location")
public Long getZipCode() {
    return zipCode;
}

public void setZipCode(Long zipCode) {
    this.zipCode = zipCode;
}

@XmlElement(name = "location")
@ApiProperty(notes = "The zip code for this location", required = false)
public String getLocation() {
    return location;
}

public void setLocation(String location) {
    this.location = location;
}
}

The expected result: the target spec doc contains 3 documented model beans in the corresponding describing tables for Customer, Address and Email.
The actual result: only Customer model bean is documented.

New feature: new property to specify or remove ".{format}" template from generated api json

Hello!

That would be great to have a plugin configuration option to specify or remove ".{format}" template from the generated path in the json api:

    {
        "apiVersion" : "1.0-SNAPSHOT",
        "swaggerVersion" : "1.1",
        "basePath" : "http://localhost:8080/contextPath/services",
        "resourcePath" : "/customer",
        "apis" : [ {
            "path" : "/customer.{format}/all",
            "description" : "Customer's operations",
            "operations" : [ {
                "httpMethod" : "GET, POST",
                "summary" : "Find all customers",
                "notes" : "Search for all customers and returns them in a collection",
                "responseClass" : "List[customer]",
                "nickname" : "getAllCustomers"
            } ]
        }

I mean to have "path" : "/customer/all" instead of "path" : "/customer.{format}/all" in case of removing .{format} template.

What do you think?

ApiResponses, ApiErrors, mustache template, maven-plugin

I am trying to render a confluence markup using maven plugin and my custom mustache template.

The latest dependency:

    <dependency>
        <groupId>com.wordnik</groupId>
        <artifactId>swagger-jaxrs_2.10</artifactId>
        <version>1.3.2</version>
    </dependency>

depends on swagger-core and in turn on swagger-annotations. The examples I saw about annotating the REST methods are using @ApiResponses and @ApiResponse which seems correct as @ApiErrors and @ApiError are not present anymore.

In my custom mustache template which is derived from https://raw.github.com/kongchen/api-doc-template/master/v1.1/wiki.mustache. This template includes a section

h4. Errors
|| Status Code || Reason ||
{{#errorResponses}}
|{{code}}|{{{reason}}}|
{{/errorResponses}}

which is giving me trouble.

My class is annotated with
@ApiResponses( value = {
@ApiResponse(code = 400, message = "Wrong paramaters were given for this services's method."),
@ApiResponse(code = 404, message = "No bicikelj data found for given parameters.")
})

and the above is not rendered even if I change the mustache template to something like:

|| HTTP Status || Description ||
{{#responses}}
|{{code}}|{{{message}}}|
{{/responses}}

Am I doing something wrong or is there a bug?

Regards

Integrating with swagger-ui

I'm generating json for my service descriptions via this configuration of the plugin:

                <configuration>
                    <apiSources>
                        <apiSource>
                            <locations>org.mypackage.services;</locations>
                            <apiVersion>v1</apiVersion>
                            <basePath>http://localhost:8080/plus/api</basePath>
                            <outputTemplate>${basedir}/src/main/resources/apidocs.template</outputTemplate>                                     
                            <outputPath>${basedir}/src/main/webapp/apidocs.html</outputPath>
                            <swaggerDirectory>src/main/webapp/apidocs</swaggerDirectory>
                            <useOutputFlatStructure>true</useOutputFlatStructure>
                            <mustacheFileRoot>${basedir}/src/main/resources/</mustacheFileRoot>
                        </apiSource>
                    </apiSources>
                </configuration>

This is creating a directory called apidocs that contains services.json, but swagger-ui is expecting a single file called apidocs that indicates which other resources json files to load. How can I get the services.json file to end up getting named apidocs so that swagger-ui can read it appropriately? When I point swagger-ui at the correct services.json file, it interprets all of my resources as sub-directories (i.e. services.json/actors.json rather than files in the same directory.

Supporting for @XmlRootElement("...")

Hello. First of all thank you for a great work!

I have discovered this issue during generating docs on my services. Services were done using RESTeasy reference implementation and base on JAXB annotated model beans.

The problem is the plugin doesn't generate the output table for model bean with is annotated with @XmlRootElement("customer").

Here is an example of such model bean:

@XmlRootElement(name = "customer")
public class Customer implements Entity<Integer> {

private String name;
private String surname;

/**
 * {@inheritDoc}
 */
@XmlElement(name = "id")
@ApiProperty(required = true, notes = "Customer's identifier")
@Override
public Integer getId() {
    return id;
}

/**
 * {@inheritDoc}
 */
@Override
public void setId(Integer id) {
    this.id = id;
}

@XmlElement(name = "surname")
@ApiProperty(required = true, notes = "Customer's surname")
public String getSurname() {
    return surname;
}

public void setSurname(String surname) {
    this.surname = surname;
}

@XmlElement(name = "name")
@ApiProperty(required = true, notes = "Customer's name")
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}
}

The expected result: the target model bean table is generated in the final docs page
The actual result: there is a link to the customer bean and the header of the table with field names but there is not any information about these fields.
The end of the generated html page:
<h3>Data Types</h3>
<h4><a name="customer">customer</a></h4>

<div>
<table>
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Access</th>
<th>Schema</th>
<th>Notes</th>
</table>
</div>
</div>
</body>
</html>

P.S. If the @XmlRootElement is commented the result is:
<h3>Data Types</h3>
<h4><a name="Customer">Customer</a></h4>

<div>
<table>
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Access</th>
<th>Schema</th>
<th>Notes</th>
<tr>
<th>id</th>
<td>int</td>
<td>true</td>
<td></td>
<td></td>
<td>Customer's identifier</td>
</tr>
<tr>
<th>name</th>
<td>string</td>
<td>true</td>
<td></td>
<td></td>
<td>Customer's name</td>
</tr>
<tr>
<th>surname</th>
<td>string</td>
<td>true</td>
<td></td>
<td></td>
<td>Customer's surname</td>
</tr>
</table>
</div>
</div>
</body>
</html>

Data Model Property Ordering with use of Position

For the API operations annotation there is a position property that can affect the order of operations are listed.

The position property seems to be also supported by @ApiModelProperty annotation. However, this does not seem to have any effect on the generated output.

Is this an issue in the plugin?
Thanks.

REST services and API docs can't be located at different URLs

I have the following plugins configuration:

        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <webResources>
                        <resource>
                            <directory>${build.directory}/restapi</directory>
                            <targetPath>restapi</targetPath>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>

            <!-- Swagger plugin -->
            <plugin>

                <groupId>com.github.kongchen</groupId>
                <artifactId>swagger-maven-plugin</artifactId>
                <version>${maven.swagger.plugin.version}</version>
                <configuration>
                    <apiSources>
                        <apiSource>
                            <locations>com.simba.rest</locations>
                            <apiVersion>v1</apiVersion>
                            <withFormatSuffix>false</withFormatSuffix>
                            <useOutputFlatStructure>false</useOutputFlatStructure>
                            <swaggerDirectory>${build.directory}/restapi/doc</swaggerDirectory>
                            <basePath>http://localhost:8080/rest</basePath>
                            <outputPath>${build.directory}/restapi/doc/rest.html</outputPath>
                            <outputTemplate>
                                https://raw.github.com/kongchen/api-doc-template/master/v1.1/html.mustache
                            </outputTemplate>
                        </apiSource>
                    </apiSources>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>

As you see, my REST API located at "http://localhost:8080/rest" (basePath).
Generated API docs with swagger-ui files are located at "http://localhost:8080/restapi".

When I fetch service.json in swagger-ui, it looks like the following JSON document:

{
  "apiVersion" : "v1",
  "swaggerVersion" : "1.1",
  "basePath" : "http://localhost:8080/rest",
  "apis" : [ {
    "path" : "/scripts.{format}",
    "description" : "Scripts"
  }, {
    "path" : "/files.{format}",
    "description" : "Operations with resource files"
  }, {
    "path" : "/directories.{format}",
    "description" : "Operations with resource directories"
  } ]
}

Swagger-UI uses "basePath" ("http://localhost:8080/rest") to retrieve other REST services ("scripts", "directories", etc), but I haven't got API docs there. They are located at "/restapi/doc".

I investigated differences between generated files (swagger-maven-plugin vs swagger-jersey-jaxrs) and found the following moment: swagger-jersey-jaxrs doesn't configure "basePath" for root document ("service.json"), only for children.

I've tried to remove basePath from service.json (modified plugin sources) but it didn't help. Swagger-ui wants to fetch children docs using incorrect path, ex "http://localhost:8080/restapi/doc/service.json/directories.json".

Have you got any idea?

swaggerUIDocBasePath should be used for service.json only

So service.json needs the swaggerUIDocBasePath set so that it swagger ui can correctly load the subsequent *.json files - however it appears to be used to set the basepath in all the rest class json files as well.

for annotated rest classes/methods the basePath parameter should be used to set the base path in the generated json.

Here's my maven config - pointing swagger-ui at http://localhost:8080/epo-jboss/apidocs/service.json now 'works' by loading all the subsequent rest class json files, but using try it fails - attempts to use http://localhost:8080/epo-jboss/apidocs rather than http://localhost:8080/epo-jboss/rest as specified

maven plugin built with clone pulled today

<groupId>com.github.kongchen</groupId>
                <artifactId>swagger-maven-plugin</artifactId>
                <version>2.2-SNAPSHOT</version>
                <configuration>
                    <apiSources>
                        <apiSource>
                            <locations>com.intuit.ctg.devops.epo.restapi;com.intuit.ctg.devops.epo.rest</locations>
                            <apiVersion>v1</apiVersion>
                            <basePath>http://localhost:8080/epo-jboss/rest</basePath>
                            <outputTemplate>
                                https://raw.github.com/kongchen/api-doc-template/master/v2.0/markdown.mustache
                            </outputTemplate>
                            <outputPath>target/generated-apis/apidocs/strapdown.html</outputPath>
                            <swaggerUIDocBasePath>http://localhost:8080/epo-jboss/apidocs</swaggerUIDocBasePath>
                            <swaggerDirectory>target/generated-apis/apidocs</swaggerDirectory>
                            <useOutputFlatStructure>false</useOutputFlatStructure>
                            <!--mustacheFileRoot>${basedir}/src/main/resources/</mustacheFileRoot -->
                        </apiSource>
                    </apiSources>
                </configuration>

2.0-SNAPSHOT dependency resolution issue

I am trying to use the 2.0-SNAPSHOT and I added the following to my POM:

    <pluginRepositories>
      <pluginRepository>
        <id>sonatype-snapshot</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
        <releases>
          <enabled>false</enabled>
        </releases>
        <snapshots>
          <enabled>true</enabled>
        </snapshots>
      </pluginRepository>
    </pluginRepositories>

This is how my plugin section looks:

        <plugin>
            <groupId>com.github.kongchen</groupId>
            <artifactId>swagger-maven-plugin</artifactId>
            <version>2.0-SNAPSHOT</version>
            <configuration>
                <apiSources>
                    <apiSource>
                        <locations>com.mycom.platform.services.api</locations>
                        <apiVersion>v1</apiVersion>
                        <basePath>http://my.basepath.com/v1/</basePath>
                        <outputTemplate>
                                 https://raw.github.com/kongchen/api-doc-template/master/v1.1/strapdown.html.mustache
                        </outputTemplate>
                        <outputPath>target/apidocs/index.html</outputPath>
                        <swaggerDirectory>target/apidocs</swaggerDirectory>
                    </apiSource>
                </apiSources>
            </configuration>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

But I keep getting this error:

[WARNING] The POM for com.github.kongchen:swagger-maven-plugin:jar:2.0-SNAPSHOT is missing, no dependency information available
........
[ERROR] Plugin com.github.kongchen:swagger-maven-plugin:2.0-SNAPSHOT or one of its dependencies could not be resolved: Failed to read artifact descriptor for com.github.kongchen:swagger-maven-plugin:jar:2.0-SNAPSHOT: Failure to find com.github.kongchen:swagger-maven-plugin:pom:2.0-SNAPSHOT in http://myurl.com/content/groups/repo was cached in the local repository, resolution will not be reattempted until the update interval of scm-int-repository has elapsed or updates are forced -> [Help 1]

--su

Adding dependency for external jars is producing ClassNotFoundException

I've added servlet-api 2.5 in pom dependencies and the class compilation is working fine. However the static doc generation is failing with class not found exception for HttpServletRequest, see stacktrace below

Number of foreign imports: 1
import: Entry[import from realm ClassRealm[maven.api, parent: null]]


at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:125)
... 20 more

Caused by: java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2451)
at java.lang.Class.privateGetPublicMethods(Class.java:2571)
at java.lang.Class.getMethods(Class.java:1429)
at com.wordnik.swagger.core.ApiSpecParserTrait$class.parse(ApiReader.scala:62)
at com.wordnik.swagger.jaxrs.JaxrsApiSpecParser.parse(JaxrsApiReader.scala:69)
at com.github.kongchen.swagger.docgen.mavenplugin.MavenDocumentSource.getDocFromClass(MavenDocumentSource.java:73)
at com.github.kongchen.swagger.docgen.mavenplugin.MavenDocumentSource.loadDocuments(MavenDocumentSource.java:46)
at com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo.execute(ApiDocumentMojo.java:52)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
... 20 more
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpServletRequest
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:244)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230)
... 30 more

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.