Fitnesse error when used with spotify maven plugin and docker - java

I am using spotify maven plugin to create a fitnesse docker image and run it on a container. I am able to bring the fitnesse up and run the tests successfully locally without using spotify maven plugin and docker but not when I use those.
I get the following error when I start the fitnesse
Error message
Here is the contents of FrontPage fitnesse wiki which generally generally takes care of resolving dependencies as per http://blog.xebia.com/fitnesse-and-dependency-management-with-maven/
!contents
!define TEST_SYSTEM {slim}
!pomFile pom.xml
!note Release ${FITNESSE_VERSION}
Here is the contents of my pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadeTestJar>true</shadeTestJar>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>fitnesseMain.FitNesseMain</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<baseImage>${docker.registry.host.slash}mcpi/service</baseImage>
<entryPoint>["java","-jar","${serviceBin}/${finalJarName}.jar","-p","8000"]</entryPoint>
<imageName>mcpi/${project.name}</imageName>
<runs>
<run>mkdir -p ${serviceHome}</run>
</runs>
<workdir>${serviceHome}</workdir>
<resources>
<resource>
<targetPath>${serviceHome}</targetPath>
<directory>${basedir}/src/test/resources</directory>
</resource>
<resource>
<targetPath>${serviceBin}</targetPath>
<directory>${basedir}/target</directory>
<include>${finalJarName}.jar</include>
</resource>
<resource>
<targetPath>${serviceBin}</targetPath>
<directory>${basedir}/target</directory>
<include>${finalTestJarName}.jar</include>
</resource>
<resource>
<targetPath>${serviceBin}</targetPath>
<directory>${basedir}</directory>
<include>pom.xml</include>
</resource>
</resources>
</configuration>
</plugin>

I believe your problem might be that you don't include your maven settings and repository in the docker image, so the !pomFile does not work inside your docker image.
Having said that: you probably don't need it, since you bundle all your classes and dependencies (at least I assume that what the 'shade plugin' does for you). So you can probably disable the 'maven class path plugin, to prevent the problem you experience now. Disabling the maven classpath plugin can be done by adding -Dfitnesse.wikitext.widgets.MavenClasspathSymbolType.Disable=true to your Java command line starting FitNesse in docker (or by removing the line from the wiki page of course, but that impacts how you work locally).
But I don't know whether your tests will work immediately, or that you have to do something extra to ensure the generated 'final jar' is on the class path of the Java process that is started once an actual test is started (but you can try that locally by running with the !pomFile removed and starting from the jar created by the shade plugin).

Fitnesse was unable to parse pom.xml as maven is not set up in docker. Instead of !pomFile pom.xml in my fitnesse wiki, I used !path path/to/jars/*.jar.
Though above error was gone, maven-shade-plugin could not resolve all the dependencies like spring-test.
I had to add maven-dependency-plugin to pom.xml so that all the dependencies are resolved <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/dependencies</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<excludeTransitive>true</excludeTransitive>
</configuration>
</execution>
</executions>
</plugin>
and moved those to docker using spotify docker-maven-plugin
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<baseImage>${docker.registry.host.slash}service</baseImage>
<entryPoint>["java","-jar","${serviceBin}/${finalJarName}.jar","-p","8000"]</entryPoint>
<imageName>mcpi/${project.name}</imageName>
<runs>
<run>mkdir -p ${serviceHome}</run>
</runs>
<workdir>${serviceHome}</workdir>
<resources>
<resource>
<targetPath>${serviceHome}</targetPath>
<directory>${basedir}/src/test/resources</directory>
</resource>
<resource>
<targetPath>${serviceBin}</targetPath>
<directory>${basedir}/target</directory>
<include>${finalJarName}.jar</include>
</resource>
<resource>
<targetPath>${serviceBin}</targetPath>
<directory>${basedir}/target</directory>
<include>${finalTestJarName}.jar</include>
</resource>
<resource>
<targetPath>${serviceBin}</targetPath>
<directory>${basedir}/target/dependencies</directory>
</resource>
</resources>
</configuration>
</plugin>

Related

Getting a logback.xml from a dependency jar and filtering it with the maven-war-plugin

We have a common logback.xml file that we would like to use across different web apps. It includes a RollinFileAppender which should see files named as the project artifactId. The logback.xml includes a property like so
<property name="LOG_FILE_NAME" value="$project.artifactId}"/>
Within our web project we would like to include a dependency e.g. logging-setup
<dependency>
<groupId>our.group.id</groupId>
<artifactId>logging-setup</artifactId>
</dependency>
How do we easily allow the maven-war-plugin to filter this file so that the ${project.artifactId} reference is replaced with the actual project.artifactId? I think it can be done using a combination of the maven-dependency-plugin and the maven-war-plugin something like below. However that would need to be included in every project POM. Is there an easier way?
Thanks,
Paul
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
<executions>
<execution>
<id>unpack</id>
<phase>compile</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>our.group.id</groupId>
<artifactId>logging-setup</artifactId>
<version>${logging-setup.version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
<includes>**/logback.xml</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
<targetPath>WEB-INF/classes</targetPath>
<includes>
<include>logback.xml</include>
</includes>
</resource>
</webResources>
<packagingExcludes>WEB-INF/lib/logging-setup-*.jar</packagingExcludes>
</configuration>
</plugin>
</plugins>
</build>
After this logback.xml file is put inside an artifact jar file, it cannot be changed easily anymore during build time.
I would suggest a slightly different approach:
rename this file to e.g. logback-YOURCOMPANY.xml and change it so it can be included.
create a tiny logback.xml file put in each project as-is which sets the property as you do, and then includes logback-YOURCOMPANY.xml
enable filtering on this tiny logback.xml file so the variable is expanded during Maven build.
See https://logback.qos.ch/manual/configuration.html#fileInclusion for details.

Maven Doesnot Overwrite files in target folder

I am using maven for build, downloading war from artifactory and in src/main/webapp/WEB-INF/ folder customized one of the file but in target//WEB_INF/ the file is not overwriting with the customized file in the final war.
I used true in maven resources plugin.
EG:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>copy-app</id>
<!-- <phase>process-resources</phase> -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<overwrite>true</overwrite>
<outputDirectory>${project.artifactId}-${project.version}/WEB-INF</outputDirectory>
<resources>
<resource>
<directory>src/main/webapp/WEB_INF</directory>
<includes>
<include>app.xml</include></includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
First run mvn clean which will remove target, and then run mvn install should create artifact with latest changes.
if mvn clean is not removing target folder, check if there are any access issues

Log4j.properties not found using maven resources folder

I try to load a configuration for log4j using the PropertyConfigurator.configure("log4j.properties") method but I keep running into java.io.FileNotFoundException.
I followed this question and placed my log4j.properties file into the resources folder.
I Also edited my pom.xml like this :
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<targetPath>${project.build.directory}</targetPath>
<includes>
<include>log4j.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>src.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
So when I run mvn package the target folder generated contains my .jar and my log4j.properties side by side but when I run my jar I get the file not found exception.
How can I fix this issue ?
Note :
Please, DO NOT include the log4j.properties into the final Jar file, it will cause multiple log4j.properties files in the classpath, if someone is depending on your Jar, you may accidentally override their logging configurations, depends which Jar is loaded first.
For reference :
https://www.mkyong.com/maven/maven-exclude-log4j-properties-in-jar-file/

Howto copy README.md into src/main/resources?

I want to show README.md file like help page in my web application. In order not to create duplicate, I need to copy by mvn from project path into resources.
How can I do so?
Any idea?
I have tried:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.3</version>
<configuration>
<!-- this is important -->
<overwrite>true</overwrite>
<!-- target -->
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resources>
<resource>
<!-- source -->
<directory>/</directory>
<include>
<filter>**/README.md</filter>
</include>
</resource>
</resources>
</configuration>
</plugin>
The simplest solution would be to move the appropriate file(s) to src/main/resources folder whereas the second solution could be like this:
<build>
<resources>
<resource>
<directory>${project.basedir}</directory>
<includes>
<include>README.md</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
No need for maven-resources-plugin to be configured this can be handled by the usual life cylcle and resource handling. The only thing you might need to adapt is the folder where the README.md is located. If you like having filtering you need to add the <filtering>true</filtering> part as well.
Copying something via Maven during the build into src/** is in general a bad idea, cause those folders are controled by version control systems which will result in uncommitted changes which you don't like to have.
Note: It would be wise to check for up-to-date versions of plugins (cause 2.3 is of 2008!). The list of the current plugin versions can be found here: http://maven.apache.org/plugins/
This works for me in one of my projects:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<!-- when to execute copy operation -->
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${basedir}/pathTo.MD</directory>
</resource>
</resources>
<overwrite>true</overwrite>
<outputDirectory>${project.build.directory}/${project.build.finalName}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
I see that i have the phase and the goal extra from your version. I also used variables for the output location.
I would recommend you to be more equal to this example: http://maven.apache.org/plugins/maven-resources-plugin/examples/copy-resources.html
With "more equal" I mean like using <executions> tag.
You can of course leave out things like <id> and filtering.
The following worked fine for me:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>myID</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/extra-resources</outputDirectory>
<overwrite>true</overwrite>
<resources>
<resource>
<directory>src</directory>
<!-- Details about filtering: http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html -->
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>

Maven compile with multiple src directories

Is there a way to compile multiple java source directories in a single maven project?
You can add a new source directory with build-helper:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/generated</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I naively do it this way :
<build>
<finalName>osmwse</finalName>
<sourceDirectory>src/main/java, src/interfaces, src/services</sourceDirectory>
</build>
This worked for me
<build>
<sourceDirectory>.</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<includes>
<include>src/main/java/**/*.java</include>
<include>src/main2/java/**/*.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
To make it work in intelliJ, you can also add generatedSourcesDirectory to the compiler plugin this way:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<generatedSourcesDirectory>src/main/generated</generatedSourcesDirectory>
</configuration>
</plugin>
This also works with maven by defining the resources tag. You can name your src folder names whatever you like.
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.java</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/generated</directory>
<includes>
<include>**/*.java</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
This worked for with maven 3.5.4 and now Intellij Idea see this code as source:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<generatedSourcesDirectory>src/main/generated</generatedSourcesDirectory>
</configuration>
</plugin>
While the answer from evokk is basically correct, it is missing test classes.
You must add test classes with goal add-test-source:
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>target/generated/some-test-classes</source>
</sources>
</configuration>
</execution>
Used the build-helper-maven-plugin from the post - and update src/main/generated. And mvn clean compile works on my ../common/src/main/java, or on ../common, so kept the latter. Then yes, confirming that IntelliJ IDEA (ver 10.5.2) level of the compilation failed as David Phillips mentioned.
The issue was that IDEA did not add another source root to the project. Adding it manually solved the issue. It's not nice as editing anything in the project should come from maven and not from direct editing of IDEA's project options. Yet I will be able to live with it until they support build-helper-maven-plugin directly such that it will auto add the sources.
Then needed another workaround to make this work though. Since each time IDEA re-imported maven settings after a pom change me newly added source was kept on module, yet it lost it's Source Folders selections and was useless. So for IDEA - need to set these once:
Select - Project Settings / Maven / Importing / keep source and test
folders on reimport.
Add - Project Structure / Project Settings / Modules / {Module} / Sources / Add Content Root.
Now keeping those folders on import is not the best practice in the world either, ..., but giving it a try.
This can be done in two steps:
For each source directory you should create own module.
In all modules you should specify the same build directory: ${build.directory}
If you work with started Jetty (jetty:run), then recompilation of any class in any module (with Maven, IDEA or Eclipse) will lead to Jetty's restart. The same behavior you'll get for modified resources.
In the configuration, you can use <compileSourceRoots>.
oal: org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-cli)
[DEBUG] Style: Regular
[DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>
<configuration>
<basedir default-value="${basedir}"/>
<buildDirectory default-value="${project.build.directory}"/>
<compilePath default-value="${project.compileClasspathElements}"/>
<compileSourceRoots default-value="${project.compileSourceRoots}"/>
<compilerId default-value="javac">${maven.compiler.compilerId}</compilerId>
<compilerReuseStrategy default-value="${reuseCreated}">${maven.compiler.compilerReuseStrategy}</compilerReuseStrategy>
<compilerVersion>${maven.compiler.compilerVersion}</compilerVersion>
<debug default-value="true">${maven.compiler.debug}</debug>
<debuglevel>${maven.compiler.debuglevel}</debuglevel>
<encoding default-value="${project.build.sourceEncoding}">${encoding}</encoding>
<executable>${maven.compiler.executable}</executable>
<failOnError default-value="true">${maven.compiler.failOnError}</failOnError>
<failOnWarning default-value="false">${maven.compiler.failOnWarning}</failOnWarning>
<forceJavacCompilerUse default-value="false">${maven.compiler.forceJavacCompilerUse}</forceJavacCompilerUse>
<fork default-value="false">${maven.compiler.fork}</fork>
<generatedSourcesDirectory default-value="${project.build.directory}/generated-sources/annotations"/>
<maxmem>${maven.compiler.maxmem}</maxmem>
<meminitial>${maven.compiler.meminitial}</meminitial>
<mojoExecution default-value="${mojoExecution}"/>
<optimize default-value="false">${maven.compiler.optimize}</optimize>
<outputDirectory default-value="${project.build.outputDirectory}"/>
<parameters default-value="false">${maven.compiler.parameters}</parameters>
<project default-value="${project}"/>
<projectArtifact default-value="${project.artifact}"/>
<release>${maven.compiler.release}</release>
<session default-value="${session}"/>
<showDeprecation default-value="false">${maven.compiler.showDeprecation}</showDeprecation>
<showWarnings default-value="false">${maven.compiler.showWarnings}</showWarnings>
<skipMain>${maven.main.skip}</skipMain>
<skipMultiThreadWarning default-value="false">${maven.compiler.skipMultiThreadWarning}</skipMultiThreadWarning>
<source default-value="1.6">${maven.compiler.source}</source>
<staleMillis default-value="0">${lastModGranularityMs}</staleMillis>
<target default-value="1.6">${maven.compiler.target}</target>
<useIncrementalCompilation default-value="true">${maven.compiler.useIncrementalCompilation}</useIncrementalCompilation>
<verbose default-value="false">${maven.compiler.verbose}</verbose>
</configuration>
these are all the configurations available for 3.8.1 version of compiler plugin. Different versions have different configurations which you can find by running your code with -X after the general mvn command. Like
mvn clean install -X
mvn compiler:compile -X
and search with id or goal or plugin name
This may help with other plugins too. Eclipse, intelliJ may not show all configurations as suggestions.

Categories

Resources