Can maven tell eclipse to ignore warnings in generated code?

1.8k views Asked by At

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.

1

There are 1 answers

2
khmarbaise On

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 a 2.4.0-SNAPSHOT where you should use 3.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...