I have a collection of Java projects. It is a series of APIs. I am generating much of the server code from the swagger definition using swagger codegen. I'm using spring-boot with the delegate pattern, so my generated code all goes to src/gen/java/main
and I can write my implementation code in src/main/java
. The generated code is not version controlled, but re-generated as needed by the maven swagger codegen plugin. All this works nicely :)
However, when I first import the projects into Eclipse (using "import existing maven project" on the parent project to import them all) I get a bunch of "unused function" type warnings from the generated code. (I add the src/gen/java/main
folder as a source folder using the build-helper-maven-plugin.) If I select the src/gen/java/main
folder in each project, right-click, choose properties and say Ignore optional compile problems then this goes away (I also mark it as a derived resource)
Question: is there some way to mark this folder in the pom so that when I (or a colleague) imports the project into Eclipse, these settings are already set on that folder? Alternatively, some way to tell eclipse to always treat folders with the name (relative to project route) in that fashion?
Additional Info
I was asked for the pom file in a comment. I have done a fairly minimal example:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.api</groupId>
<artifactId>com.example.api</artifactId>
<packaging>jar</packaging>
<name>Example</name>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<springfox-version>2.7.0</springfox-version>
<swagger.codegen.version>2.4.0-SNAPSHOT</swagger.codegen.version>
<jetty-version>9.2.15.v20160210</jetty-version>
<slf4j-version>1.7.21</slf4j-version>
<junit-version>4.12</junit-version>
<servlet-api-version>2.5</servlet-api-version>
<springfox-version>2.7.0</springfox-version>
<jackson-version>2.8.9</jackson-version>
<jackson-threetenbp-version>2.6.4</jackson-threetenbp-version>
<spring-version>4.3.9.RELEASE</spring-version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<versionRange>${swagger.codegen.version}</versionRange>
<goals>
<goal>generate</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<mainClass>${start-class}</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.example.api.Swagger2SpringBoot</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Needed to create swagger bits in asynch manner -->
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>${swagger.codegen.version}</version>
<executions>
<execution>
<id>foo</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/spec/foo.yaml</inputSpec>
<modelPackage>com.example.api.models</modelPackage>
<apiPackage>com.example.api</apiPackage>
<language>spring</language>
<invokerPackage>com.example.api</invokerPackage>
<basePackage>com.example.api</basePackage>
<withXml>true</withXml>
<configOptions>
<artifactId>bookings</artifactId>
<artifactDescription>Bookings API</artifactDescription>
<title>Bookings API</title>
<artifactUrl>https://api.example.com/foo</artifactUrl>
<groupId>com.example.api</groupId>
<artifactVersion>1.0</artifactVersion>
<configPackage>com.example.api.config</configPackage>
<serializableModel>true</serializableModel>
<dateLibrary>java8</dateLibrary>
<java8>true</java8>
<async>true</async>
<library>spring-boot</library>
<delegatePattern>true</delegatePattern>
<useBeanValidation>true</useBeanValidation>
<useOptional>true</useOptional>
<hideGenerationTimestamp>true</hideGenerationTimestamp>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-version}</version>
<configuration>
<webAppConfig>
<contextPath>/v2</contextPath>
</webAppConfig>
<webAppSourceDirectory>target/${project.artifactId}-${project.version}</webAppSourceDirectory>
<stopPort>8079</stopPort>
<stopKey>stopit</stopKey>
<httpConnector>
<port>8002</port>
<idleTimeout>60000</idleTimeout>
</httpConnector>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!--SpringFox dependencies -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<!-- Bean Validation API support -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
</project>
This uses a minimal foo.yaml:
swagger: '2.0'
info:
title: Foo API
description: Test case
version: 1.0
host: api.example.com
basePath: /
schemes:
- https
consumes:
- application/json
produces:
- application/json
tags:
- name: foo
parameters:
message:
name: message
in: body
description: Foo
schema:
$ref: '#/definitions/Message'
required: true
definitions:
Message:
type: object
description: Foo
properties:
heading:
type: string
description: heading
body:
type: string
description: body
paths:
/foo:
post:
summary: foo
operationId: postFoo
tags:
- foo
parameters:
- $ref: '#/parameters/message'
responses:
'202':
description: Messages will be sent
default:
description: An unexpected error occurred
If I just mvn clean compile
then import this the it's fine. However, if I add any implementation code that uses the generated code then it isn't.
For example, I added a package com.example.api.implementation
to src/main/java
containing a file FooApi.java which was:
package com.example.api.implementation;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import com.example.api.FooApiDelegate;
import com.example.api.models.Message;
import com.fasterxml.jackson.databind.ObjectMapper;
@Component
public class FooApi implements FooApiDelegate {
private final ObjectMapper objectMapper;
private final HttpServletRequest request;
public Optional<ObjectMapper> getObjectMapper() {
return Optional.ofNullable(objectMapper);
}
public Optional<HttpServletRequest> getRequest() {
return Optional.ofNullable(request);
}
@org.springframework.beans.factory.annotation.Autowired
public FooApi(ObjectMapper objectMapper, HttpServletRequest request) {
this.objectMapper = objectMapper;
this.request = request;
}
@Override
public CompletableFuture<ResponseEntity<Void>> postFoo( Message message) {
return new CompletableFuture<ResponseEntity<Void>>();
}
}
If I now import, I get errors FooApiDelegate cannot be resolved to a type and Message cannot be resolved to a type (and for the corresponding imports) from my non.generated file.
There are at least two issues. The first thing is that you explicitly suppressed the execution of the code generation by using
org.eclipse.m2e
.. this will suppress any kind of generation you might have. Furthermore you are using a2.4.0-SNAPSHOT
where you should use3.0.0-rc0
instead. Unfortunately the 3.0.0-rc0 has failured so you should stick with 2.3.1 which is a release instead of SNAPSHOT's.Apart from that the plugin is missing also things are not correctly handled...If you cleanly import the project in Eclipse you will get a dialog about
Setup Maven Plugin Connectors
. Furthermore the plugin does not correctly handle the update in Eclipse context which can be done...If you import the project and manually add the source folders from
target/generated-sources
this will work but unfortunately not allways...