Spring REST Docs maven continuous build? - spring-boot-maven-plugin

I was going through this tutorial https://www.youtube.com/watch?v=k5ncCJBarRI&t=1443s
Around 1:07:30 the author mentioned about "Gradle has continuous build" later on was able to detect changes in the test and automatically regenerate asciidoc. I was wondering if anyone knows how to set this up in maven?
I have looked through docs in spring and asciidoctor plugin, but was not able to find anything related to this.
I was able to get maven to re-render html when ever there is a change in index.adoc by changing <goal> from process-asciidoc to auto-refresh. However, this does not watch the change in the Test.
Question
Is there a way to tell Maven to watch our test files and re-compile when changes are made?
POM.XML
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.7.1</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>auto-refresh</goal>
</goals>
<configuration>
<sourceDocumentName>index.adoc</sourceDocumentName>
<backend>html</backend>
<attributes>
<snippets>${project.build.directory}/generated-snippets</snippets>
</attributes>
</configuration>
</execution>
</executions>
</plugin>
Thank you.

This is not a continuous build solution but it works similarly. However, the process does take some time because it essentially re-packages the project everytime there is a change... May not be ideal for some use cases...
I found a plugin that watches files. https://github.com/fizzed/maven-plugins
Change the watch directory to where your test files. Changed the goal from compile to package.
Watcher will execute mvnw: package when a change is detected. Then the asciidoctor maven plugin will re-package the project.
Add this to your plugin
<plugin>
<groupId>com.fizzed</groupId>
<artifactId>fizzed-watcher-maven-plugin</artifactId>
<version>1.0.6</version>
<configuration>
<touchFile>target/classes/watcher.txt</touchFile>
<watches>
<watch>
<directory><directory>src/test/[your test package]</directory></directory>
</watch>
</watches>
<goals>
<goal>package</goal>
<!-- <goal>compile</goal> -->
</goals>
<profiles>
<profile>optional-profile-to-activate</profile>
</profiles>
</configuration>
</plugin>

Maven does not have an equivalent of Gradle's continuous build. If you want changes in the tests to be detected and to trigger recompilation of the tests and execution of all of the tasks that depend (directly or indirectly) on the compiled test classes, you'll have to use Gradle.

Related

Overwriting application.conf using Maven and generating jar file

I have a Scala app (v2.13) created using Maven v3. My resources path is:
src -> main -> resources -> application.conf and aplication.prod.conf
When I generate the JAR file for production, I want to take configuration resources from application.conf, but being overwriten by application.prod.conf.
I can not found a solution for that, all founded examples are for Play framework or previous maven versions.
The JAR file is generated using maven package cmd.
application.prod.conf file
include "application.conf"
# override default (DEV) settings
http {
host = "99.999.999.9"
port = 1111
}
The following example doesn't works for me, because from target path I get only the JAR file to move it on production:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<delete file="${project.build.outputDirectory}/application.conf"/>
<copy file="src/main/resources/application.prod.conf"
tofile="${project.build.outputDirectory}/application.conf"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
Few options here:
If your application.prod.cont is static and gets shipped with jar, why cant you have a logic in the code which loads appropriate app conf based on the environment app is getting executed
Is it a typesafe config, if so, while running in prod you can pass -Dconfig.resource=/application.prod.conf java command line argument
or application.prod.conf is not shipped with jar then you can pass -Dconfig.file=/path/to/application.prod.conf
Maven has a concept of phases (we're talking about the phase package here to be precise) which are logical places in the life cycle where the plugins can be invoked. Some plugins, like the one that creates the jar, for example, are associated to phases automatically (out-of-the-box), others you define explicitly and associate with the phase (like maven-antrun-plugin which is executed during the phase package as you've showed in the code snippet).
With that in mind, Is it possible that the file is attempted to get copied after the jar was packaged, so that the antrun plugin is invoked after the artifacts were packaged into the jar?
If so, the easiest solution will be moving it to one phase before, for example prepare-package:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>prepare-package</phase> <!-- Note the change here -->
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<delete file="${project.build.outputDirectory}/application.conf"/>
<copy file="src/main/resources/application.prod.conf"
tofile="${project.build.outputDirectory}/application.conf"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
Assuming you have maven 3 (there is no maven version 4 yet so it might be a typo), the information about which phases are available in maven here
Having said that, probably its not a good idea to "bake" the configuration file of production into the artifact, two issues here:
Your source code contains the information about production - hosts, ports, maybe even sensitive information like passwords or keys - this shouldn't really happen
From the point of view of build, your artifact is coupled to concrete environment, which is also considered a bad practice basically.
The techniques to resolve this are beyond the scope of the question but at least you've been warned :)

How to compile only changed parts of gwt modules?

We decided to use gwt modules in our application about 1 week ago. We use gwt-maven-eclipse trio and we already configured phases and goals. Also we are doing context deploying to decrease development and testing time.
BUT;
When we package or tomcat:deploy our application, gwt modules are re-compiling(including unchanged ones).
<set-property name="user.agent" value="gecko1_8"></set-property>
<extend-property name="locale" values="en_UK"></extend-property>
I already set these properties up here to speed up compiling time but this is not what i want exactly...
I also configured maven lifecycle mapping in eclipse to fire gwt:compile process-resources resources:testResources when any resources change. But it blocks eclipse and that was not helpful about compiling time either.
This is gwt-maven-plugin configuration in pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>2.3.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<!--
Plugin configuration. There are many available options, see
gwt-maven-plugin documentation at codehaus.org
-->
<configuration>
<runTarget>A.jsp</runTarget>
<runTarget>B.jsp</runTarget>
<hostedWebapp>${webappDirectory}</hostedWebapp>
</configuration>
</plugin>
Any idea to help me?
gwt-maven-plugin tries (hard) to avoid recompiling modules when the code hasn't changed, but even that takes a bit of time (still less than re-compiling the module; and unfortunately if it detects the module needs to be recompiled, it adds up to the GWT compile time).
If you know you don't need gwt:compile, you can pass -Dgwt.compiler.skip=true to your Maven build to skip the goal and keep "running" your previously compiled code. Similarly, if you know you need gwt:compile, you can pass -Dgwt.compiler.force=true to bypass the "up-to-date check".

What is the correct way to specify a main class when packaging a jar using m2eclipse?

Problem:
I'd like to specify the main class in a jar file that I am packaging using m2eclipse: [right-click] -> Run As -> Maven package. I'm still learning Maven and from what I've read, the straight-up way of accomplishing this task is to add a stanza to the pom.xml.
Here are examples I found when I was researched this issue:
Cannot make executable jar using m2eclipse
http://docs.codehaus.org/pages/viewpage.action?pageId=72602
My question is this: is it okay to manually edit the pom.xml file outside of Eclipse/m2eclipse using a text editor, or should I be doing this configuration using the m2ecplise GUI? There are several tabbed dialog boxes that seem like they might be likely candidates for this task, like "Plugins" and "Build". I looked through Sonatype's documentation and couldn't find any detailed instructions on how to accomplish what I need to do.
I'm a little hesitant to edit the pom.xml manually because I notice the "Effective POM" already has a lot of extra stuff in it, including the plugin definition that needs to have added to it:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
If I understand correctly, the Effective POM needs to be changed so that the plugin is configured like this:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>[name of main class]</mainClass>
<packageName>[package name]</packageName>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${pom.url}</url>
</manifestEntries>
</archive>
</configuration>
</plugin>
Is this right? And if so, do I do this through m2eclipse or should I just copy all the extra Effective POM stuff and paste it into the actual pom.xml using a text editor?
Thanks to anyone who can shed some light.
UPDATE: I went ahead and manually edited the pom.xml file in a text editor. When I viewed Effective POM in m2eclipse it displayed everything that I put in (I assume). I built the jar and the main class was correctly set.
This seems like a hack to me though. Does anyone know if there's a way to do this configuration using m2eclipse itself? I checked the m2eclipse tabs and nothing seemed to have been updated as a result of my manual edits of pom.xml (other than the Effective POM tab).
m2eclipse doesn't do everything for you, i.e. there isn't a pretty UI tab for handling everything.
My team is most comfortable with editing the POM manually, and using the other tabs for verification (like Effective POM view).

Replace Maven Site Plugin with GWT Compile Plugin

I have successfully set up a few projects which use Maven to automatically deploy the Maven-generated site to the gh-pages branch of their git repository. GitHub then serves these files at a public URL on a personal subdomain. I'm looking to utilize this functionality to serve a rich client-side only GWT application.
I have modified my pom.xml to compile the GWT application to the target/site/ directory. The two main goals I am still attempting to achieve are:
How do I prevent the standard Maven site plugin from running during the site phase?
What is required so gwt:compile executes during the site phase?
A goal can be bound to a phase by specifying a new execution for the plugin. I'm assuming you've got some custom stuff you need to make most of this work correctly, so I'm just going to focus on what should work to bind a plugin goal to a particular phase.
<plugin>
<artifactId>gwt-maven-plugin</artifactId>
...
<executions>
<execution>
<id>gwt-site</id>
<phase>site</phase><!-- phase to bind to -->
<goals>
<goal>compile</goal><!-- goal to run in that phase -->
</goals>
<configuration>
<!-- Your magic configuration stuff goes here -->
</configuration>
</execution>
<!-- Possible other executions might be defined here -->
</executions>
</plugin>
Preventing the default maven site from being run is more interesting, as it is a phase, with a variety of goals bound to it. The standard site:site goal can be prevented from running in the site phase by explicitly specifying an execution with no goals. This may vary slightly from maven 2 to 3, so I'm going to be a little general here. Take a look at your build logs to see what is currently specified in terms of execution id, group/artifact id to correct possible oversights in my example:
<plugin>
<artifactId>maven-site-plugin</artifactId>
...
<executions>
<execution>
<phase>site</phase>
<goals></goals><!-- This is empty to indicate that no goals should be run in this phase -->
</execution>
</executions>
</plugin>

How to copy dependencies to gae war/WEB-INF/lib

I'm coming from Ant perspective, so pardon me. I realise there are quite a few questions here already on how to maven dependencies, but none of them seem to tell how to do what need to do.
Question 1:
Currently, in conjunction with using maven-war-plugin, when I run mvn war:war, it creates a war folder in target folder.
However, I wish copy all the dependencies' jars to war/WEB-INF/lib set up by google eclipse plugin (with gae enabled, gwt disabled), without overwriting the jars that google eclipse plugin placed there.
I don't wish to setup a war file or war directory. I just need to copy/consolidate all the non-gae jars with the gae jars so that when the project is run as a gae web app, Eclipse would not complain ClassNotFoundException.
Question 2:
When using Ant in Eclipse, I could run Ant targets within Eclipse.
Right now, I have to perform mvn commands from a shell window (which is mutually oblivious to the existence of an Eclipse session). It appears that the only thing that is automatically done is whenever I update dependencies.
Is there a way, or any plugin for eclipse that would allow me to run mvn goals within Eclipse?
Additional info:
mvn dependency:copy-dependencies persists in copying to target/dependency directory, with the following:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/war/WEB-INF/lib/</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<excludeArtifactIds>gwt-user,gwt-dev</excludeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
I even tried changing to absolute path
<outputDirectory>
/home/geek/eclipse/workspace/Demo-autoshoppe/holycow
</outputDirectory>
But holycow directory is still empty and mvn still persists in copying to target/dependency directory. My current solution is to softlink target/dependency as war/WEB-INF/lib, which is a very very bad kludge. Why is maven not sensitive to outputDirectory specification? I am using Ubuntu's maven 2.2.
I have the real answer for you, my man.
Use the "default-cli" execution id. Make sure you're using Maven 2.2+. This exec-id applies to command-line executions of the mojo.
<build>
<pluginManagement>
<plugins>
<!-- Copy dependencies to war/WEB-INF/lib for GAE proj compliance. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/war/WEB-INF/lib/</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<excludeArtifactIds>gwt-user,gwt-dev</excludeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
Cheers.
An associate emailed me this answer which works. Trigger the follow through
mvn build or mvn package
but not directly thro mvn dependency:copy-dependencies.
<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}/war/WEB-INF/lib/</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<excludeArtifactIds>gwt-user,gwt-dev</excludeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
Regarding #1: I'd suggest creating your maven project based off this plugin and archetype http://code.google.com/p/maven-gae-plugin/ (see the GWT based example if you are writing a GWT app for GAE).
Regarding #2: Check out m2eclipse plugin for full maven integration in eclipse. It's written by Sonatype (the creators of maven): http://m2eclipse.sonatype.org/