Writing POM Version with use of properties file - java

I would like to write the POM Version and a timestamp in a text file.
Therefore I created a properties file in a src/main/resources/version folder with:
product.version = ${project.version}
and added to my pom.xml:
<resource>
<directory>${basedir}/src/main/resources/version</directory>
<filtering>true</filtering>
</resource>
My output textfile says this:
Version = ${project.version}
Timestamp = 277466182879304
What am I doing wrong ?

The variable is called ${project.version}, not ${pom.version}
[EDIT] Old versions of the m2e plugin could be configured not to run the resource copy target of Eclipse when Eclipse builds the project. That means for unit tests and main() methods that you launch from Eclipse, the resources won't be updated and you will see some old value.
Also make sure you force a complete rebuild of the projects when running Maven from the command line; otherwise, Eclipse will be confused and you will get strange errors.
If you have problems like this, first run Maven from the command line to see whether it's a Maven or m2e (configuration) issue.
The next step is to run Maven from within Eclipse using Run as.../Maven install. That will build the project using Maven and without the m2e shortcuts.
If those work, it's an effect of m2e which tries to cut some corners to keep Eclipse responsive. Make sure you have the latest version of m2e (1.2.0). It should fix this. If it still doesn't work, file a bug report.
This works for me: version.properties contains
version=${project.version}
timestamp=${build.time}
Because of a bug in Maven 3.x, I have to use a plugin to get a correct build timestamp:
<plugin>
<groupId>com.keyboardsamurais.maven</groupId>
<artifactId>maven-timestamp-plugin</artifactId>
<configuration>
<propertyName>build.time</propertyName>
<timestampPattern>yyyy.MM.dd HH:mm:ss</timestampPattern>
</configuration>
<executions>
<execution>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>

Related

What do I need to add to my pom.xml to run this specific Java file?

I'm not a Java dev and am unfamiliar with the packaging and building of Java programs. I'm trying to run this file: https://github.com/CodinGame/SpringChallenge2020/blob/master/src/test/java/Spring2020Main.java
by doing
mvn clean install
java -jar .\target\spring-2020-1.0-SNAPSHOT.jar
but I get this error:
no main manifest attribute, in .\target\spring-2020-1.0-SNAPSHOT.jar
I can't figure out for the life of me what I need to add to the pom.xml or whatever else I need to do to get this to work.
Any help will be appreciated.
A few things to understand about Java:
1) If you have a Maven project like this, code is divided between src/main/ and src/test/ directories. src/test/ is intended for unit tests. In your case, Spring2020Main is not actually set up as a unit test, so I'm not sure what the author intended here.
2) When you compile using mvn clean install, a jar (library) is built, but nothing from src/test will be included in the output.
Generally, tests are executed during build. And this one would have been, except it's not set up as a real junit test, so it didn't run during build.
3) You can move the file from src/test/java to src/main/java and it will be built into your resulting jar.
4) In this case, when you run the JVM, you need to specify a classpath. This is a list of all libraries to include when the application starts. You also need to specify the (fully qualified) name of the class to run:
java -cp target/spring-2020-1.0-SNAPSHOT.jar Spring2020Main
...the above won't work directly since there are more unsatisfied dependencies (the top level pom.xml brings in at least 3 other deps you'd also need to provide on the classpath).
As others pointed out, a solution could be to build a self-executing jar, but simplest for you would be to run this from an IDE:
Run this from IntelliJ. If you haven't installed it, install it.
1) File > New From Existing Sources, find the directory where this is coned to.
2) When asked, Import Project from Existing Model (Maven)
3) When the Project view is available (alt-1), or View > Tool Windows > Project, you can expand the structure till you find Spring2020Main in the test directory.
4) Right-click it and select Run.
For me, it exposed a web server running at http://localhost:8888/test.html
You can follow the steps below:
Move Spring2020Main.java to src/main/java/com/codingame directory
Add the following to your pom.xml after the </dependencies>:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.codingame.Spring2020Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Run maven build using mvn clean install
Execute the program using java -jar target/spring-2020-1.0-SNAPSHOT.jar
Info: Apache Maven Shade Plugin helps in building what is called an uber-jar or a fat-jar. This means that all the dependencies are packaged as part of the resultant jar file without the need for any 'libraries' that you'd need to add in the classpath when executing the jar file. As part of the final jar, we need to specify which file needs to be treated as the main file to be executed. This is typically done using META-INF/MANIFEST.MF file inside the uber-jar. That's what the transformer specified inside the configuration of the plugin does for us.
The project you've linked has only a basic setup for compilation (that would be enough to run it from IDE though).
What you need is an executable jar. Check this thread.
As others mentioned (and I failed to notice) the class you linked to is a test class, so it may not be included in a jar by default. Run it through IDE or set it up in a proper source directory.

How to format code according to google java format

Current state:
I have a project which is build with: Java 1.8.161, Maven 3.3.9, SpringBoot 2.0.1, tools: Jenkins and GitLab. I would like to use google java format as a standard for whole team.
My investigation / solution:
During the investigation I found solution, which sounds really easy. Just update pom file with:
<build>
<plugins>
<plugin>
<groupId>com.coveo</groupId>
<artifactId>fmt-maven-plugin</artifactId>
<version>2.5.0</version>
<executions>
<execution>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
And it works. If I run compile, package, verify, install or deploy Maven lifecycle the code is formatted.
Question:
How can I run this after i.e. each commit for all team members without any extra steps in their IDEA? Because right now, I need to run Maven before each commit. But during the run of an application it is not necessary, so the team can avoid it.. Which of course will lead to problems with history in git.
You can let pre-commit hook trigger formatter for files staged for commit.
git-code-format-maven-plugin uses google-java-format formatter and can install client-side pre-commit git hook during compile phase. It requires Maven 3.5.x, which should be enforced.
<build>
<plugins>
<plugin>
<groupId>com.cosium.code</groupId>
<artifactId>git-code-format-maven-plugin</artifactId>
<version>VERSION</version>
<executions>
<execution>
<goals>
<goal>install-hooks</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<version>VERSION</version>
<executions>
<execution>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>[3.5.4,)</version>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Point to standalone Maven in IDE as git-code-format-maven-plugin does not play along nicely with embedded Maven.
mvn compile to get hook installed. For IDEA, that's it.
As git-code-format-maven-plugin only formats changed files (which is good), it is probably good to format whole project upfront once (mvn git-code-format:format-code -Dgcf.globPattern=**/*).
Workaround for Eclipse
Because of a bug in EGit, which sometimes ignores Git hooks completely, developers using Eclipse on Windows should have Cygwin in PATH. An empty cygpath.exe will do. Run 'Command Prompt' as a administrator and execute C:\>echo "" > /"Program Files"/Git/bin/cygpath.exe (kudos to hook is not working eclipse egit client).
Reboot.
A note on java import statements ordering
Optimise imports or reformat in IDE or reformat with plugins, can lead to changes in imports ordering. A nasty surprise if an older version of git-code-format-maven-plugin is being used together with fmt-maven-plugin (to format or validate code later in CI, for example).
git-code-format-maven-plugin will sort imports (since version 1.20)
fmt-maven-plugin will always sort imports
googleformatter-maven-plugin can optionally sort imports (not per default)
In order to run this formatter after each developer commit, you will have to first have a Jenkins commit hook in place, that will trigger a Jenkins build. One of the phases of the build, should execute the fmt-maven-plugin's (or any others) check functionality in order to ensure that the code is properly formatted.
Adding a webhook
First thing to do is add a webhook that will trigger a Jenkins build after every commit in your git repository. You can find how to do this here. For Gitlab specific instructions, this post from medium may be helpful.
Executing the check
This can be done by executing the check goal on the fmt-maven-plugin
Maven acceps either <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal> as a means of calling a plugin goal, so for your specific problem, you can run:
mvn fmt:check
That being said, you will have to add a Jenkins build step, that will run the mentioned command. Step 5 from this tutorial shows you how to add a build step.
Hope that this actually helps :D
I need to run Maven before each commit
You do not need to run multiple maven goals. For eg no need to run maven install for the formatting to take place. A simple maven compile will formate the classes.

Using Maven for non-Java projects (overriding clean/compile/install goals)

I have a good(ish) understanding of using Maven for Java/WebApp projects but only to the point of following the default goals/lifecycle.
However I now have a Backup project which is not a Java project at all. I was thinking of configuring it with Maven to keep some consistency but am not sure how I override the main Maven goals/phases for my bespoke processing.
The Backup project needs to do the following:
'build' - initially, the backup outputs will be a mysql database dump file and a zip exported from an existing WebApp. But I want it to be flexible so calling an ant file to do the actual work (creating the dump, calling the WebApp, or doing whatever in the future) seems sensible. The output files could then be copied into the target directory.
'install' - publish the output files to a local repository, preferably providing a datetimestamp version number instead of the usual 1.0.0-SNAPSHOT version. I'd like to think that Maven can cope with an artefact being a collection of files, rather than a single jar/war, but not sure on this.
My pom.xml declares the packaging as 'pom' as 'jar' and 'war' dont seem appropriate here.
I then want other projects to be able to have a dependency on this Backup project so they can get the lastest backup artefacts if required.
1) how do I override the maven 'compile' goal to call an ant build file?
2) how do I override the maven 'install' goal to publish all files in the target directory but as a single artefact?
Any help/guidance appreciated.
you can use maven antrun plugin for achieving this.
one example usage:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>bundle-virgo</id>
<phase>package</phase>
<configuration>
<tasks>
<ant antfile="<path to build.xml>" target="compile"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
you can change the phase parameter to different maven phases to run it at different phases like package, compile etc.

How can I share clover coverage data between maven and IntelliJ

I have a multi-module maven project. I'm using intellij-idea as my IDE.
I have Maven configured with the clover plugin to automatically instrument on build.
How can I get IntelliJ to recognize those changes and refresh its coverage data.(NOTE: having to click the "Refresh Coverage" toolbar button is fine.)
I've tried configuring maven-clover2-plugin like so:
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-clover2-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<baseDir>${project.basedir}</baseDir>
<cloverMergeDatabase>
${project.basedir}.clover\cloverMerge.db
</cloverMergeDatabase>
</configuration>
<executions>
<execution>
<id>main</id>
<phase>package</phase>
<goals>
<goal>instrument</goal>
<goal>aggregate</goal>
<goal>check</goal>
</goals>
</execution>
<execution>
<id>site</id>
<phase>pre-site</phase>
<goals>
<goal>instrument</goal>
<goal>aggregate</goal>
<goal>check</goal>
</goals>
</execution>
<execution>
<id>clean</id>
<phase>clean</phase>
<goals><goal>clean</goal></goals>
</execution>
</executions>
</plugin>
I then configured my project settings to use:
.clover\cloverMerge.db and checked the relative to project directory. checkbox.
But that didn't work.
NOTE:
At the bottom of Configuring Instrumentation it says
Do not set these locations explicitly if you have a multi-module project.
So I also tried leaving the location as the default for both Maven and IDEA and that didn't work either.
Also in the Clover for IDEA installation GUIDE - Known Issues
If you are using the Maven build tool, you should avoid using the same > IntelliJ output directory as Maven does. As Maven uses the target/classes and target/test-classes directories,
avoid specifying these ones. The clover.db location for IntelliJ should also be distinct from that used by Maven.
WHY should they be distinct is there some file corruption issue? If they're kept distinct then HOW can I get awesome coverage highlighting/etc, without having to repeat builds in a completely separate process?
Well I finally figured out an answer. I'm leaving this here for posterity.
The solution is complicated and somewhat of a Hack but it WORKS.
Update the parent projects pom.xml file
cloverDB: <cloverDatabase>${project.basedir}.clover\clover.db</cloverDatabase>
Merge CloverDB:
<cloverMergeDatabase>
${project.basedir}.clover\cloverMerge.db
</cloverMergeDatabase>
Create your Unit Tests to Run in IntelliJ IDEA
setup a Before launch - Run Maven Goal
clean clover2:setup prepare-package -DSkipTests
Create a Maven Run Configuration
Make the Unit-Tests a Before launch condition
In the command line have Maven run clover2:aggregrate
Update Intellij Project Settings for clover to point to the merge file
Make sure the Relative to project directory. checkbox is checked.
InitString to User specified with the value the same as your pom file.
in my case: .clover\cloverMergeDB
Once the command is run, just click the Referesh Coverage icon to see and work with the coverage data in idea.
If the tests fail you will also have the nice IntelliJ Test runner Tab to figure out why.
At the bottom of Configuring Instrumentation it says
Do not set these locations explicitly if you have a multi-module project.
Documentation actually says: Do not set these locations explicitly (using absolute path) if you have a multi-module project. The reason is simple - if you use an absolute path, then you will not have a separate clover.db for every module, but only a single clover.db file.
"If you are using the Maven build tool, you should avoid using the same IntelliJ output directory as Maven does. As Maven uses the target/classes and target/test-classes directories, avoid specifying these ones" [...] WHY should they be distinct is there some file corruption issue?
The problem is as follows: IntelliJ IDEA uses it's own engine to compile sources. It means that it does not have to call the original project's build system (a Maven, for instance) to compile sources.
It means that:
- if you have a Maven-based project and it has the Clover-for-Maven plugin installed and
- at the same time you have the Clover-for-IDEA installed in the IntelliJ IDE
- and these two Clover integrations use the same output folders for classes and databases
... then these two Clover integrations may start overwriting their files.
In most cases this is not a desired behaviour because any source code modification / project rebuild action etc in IDEA will trigger source recompilation; which can delete results obtained previously by Clover-for-Maven.

Maven and GWT (and Eclipse) - Does it really work?

Over the past few days I have been trying to create/run a project in Eclipse using the gwt-maven-plugin and keep running into roadblocks (see some of my previous questions). I like to use Maven to do my builds, but I'm at the point where I'm thinking of going the Ant build route because of the complications of using Maven.
Does anyone out there have it configured/working well? Is it just me or is this harder than it should be?
After much frustration trying to get things to play nicely together, this is the setup I have that "works" for me. "Works" meaning that I can create, run and debug a GWT project with tweaks, but it isn't the most elegant solution.
Create Project
Much of the steps are the same as Pascal's answer in this post: Maven GWT 2.0 and Eclipse. I'll list mine out to be clear.
In Eclipse (Helios) with m2eclipse and GWT Eclipse plugins installed:
Create a new Maven project using the gwt-maven-plugin archetype
Modify the pom.xml:
set <gwt.version property> to 2.0.4
(needs to be same as GWT Eclipse
Plugin version)
set <maven.compiler.source> and
<maven.compiler.target> properties to
1.6
remove <goal>generateAsync</goal>
from gwt-maven-plugin <plugin> config
add maven-war-plugin to pom.xml
maven-war-plugin example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<warSourceDirectory>war</warSourceDirectory>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
</configuration>
</plugin>
Update project Properties:
Google -> Web Toolkit, check the "Use Google Web Toolkit" box, and ensure "Use default SDK (GWT-2.0.4) is selected.
Run Maven "gwt:eclipse" goal on project (sets up environment and launch config)
Copy *.launch file to workspace.metadata.plugins\org.eclipse.debug.core.launches
Restart Eclipse
Compile/Run Project
I created a Run Configuration that does mvn clean compile gwt:run. The gwt:run is necessary to copy the resources and lib jars into the war directory. However, it does not copy the web.xml from src/main/webapp/WEB-INF into war/WEB-INF/. So, I have to manually copy that file.
If I want to run my application, the above step is sufficient. However, if I want to debug the application, I launch it by choosing the Google "Web Application" configuration from Debug Configurations that was created when the .launch file was copied previously. This configuration allows for debugging (breakpoints etc.) without any other config or need for remote debugging.
It is harder then it should be, however it is possible. All hints posted here can do the trick. However you can still have classloading issues. I decided to switch to GWT 2.1 and use new abilities of JettyLauncher. You can create own jetty launcher like this:
public class MyJettyLauncher extends com.google.gwt.dev.shell.jetty.JettyLauncher {
#Override
protected WebAppContext createWebAppContext(TreeLogger logger, File appRootDir) {
return new WebAppContext(appRootDir.getAbsolutePath(), "/");
}
}
And then add -server MyJettyLauncher option to your gwt launcher configuration. With such configuration all the libraries are managed by m2eclipse (you can even remove GWT SDK from classpath) and there is no need to copy anything to WEB-INF/lib (you can remove gwt-servlet.jar which could be already there).
Ready launcher is here in tadedon library:
http://code.google.com/p/tadedon/source/browse/tadedon-gwt-dev/src/main/java/com/xemantic/tadedon/gwt/dev/JettyLauncher.java
Yes, in 2016 it does, quite nicely indeed. :)
I launch Tomcat from within Eclipse, I launch GWT codeserver (SuperDev mode) from Eclipse, I launch Chrome from Eclipse.
You will find quite recent and very valuable set-up tutorials on Brandon Donnelson's YouTube channel: https://www.youtube.com/user/branflake2267/videos
What is essential for me is Eclipse debugger for GWT SuperDevMode: https://sdbg.github.io/
I prefer to have my project "mavenized", and there is lot of Maven archetypes also provided by Brandon: https://github.com/branflake2267/Archetypes/tree/master/archetypes
The official starting point (not just) for downloading the GPE plugin (not to confuse with above mentioned debugger plugin) is on GwtProject.com: http://www.gwtproject.org/download.html
For me personally GPE itself has become rather optional "convenience" component. (Yes, refactoring and auto-completion are nice to have, but that's all it is needed for. :)
It is not a one-click solution, and I prefer it like that, as those tend to be black-boxes prone to breaking.
And BTW make sure to take a look at GWT Material: http://gwtmaterialdesign.github.io/gwt-material-demo/
(Currently playing with 2.8-beta1.)
For Eclipse I use: m2eclipse plugin (1.0). It works well with one or two minor things. Also download the m2eclipse-extras plugin to add SVN functionality AND Maven (or CVS if you prefer).
When you download then your project it reads the pom.xml and [re]creates the Eclipse configuration files like the mvn eclipse:eclipse command.
For GWT... I've used it too. It's a pretty twiked configuration but it works. I use GWT 2.0.3, the maven-gwt-plugin uses the dependencies to work (no ref to GWT SDK) and it can debug from Eclipse which is simply great.
You have to compile to a war directory (not the target/classes standard). But the details are in my work, so let me see it tomorrow and complete this answer :) Don't give up. It's a great thing to have GWT+Eclipse+Maven.
Edit: part of my configuration
<build>...
<outputDirectory>war/WEB-INF/classes</outputDirectory>
...
</build>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<gwtVersion>${gwt.version}</gwtVersion> <!-- para forzar que use el de maven y no el SDK instalado -->
<disableCastChecking>true</disableCastChecking>
<disableClassMetadata>true</disableClassMetadata>
<runTarget>/subscriber/listSubscribers.htm</runTarget>
<webappDirectory>${basedir}/war</webappDirectory>
<soyc>true</soyc>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- dont know/remember if the jetty inside the gwt uses this... but it doesnt hurt-->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.14</version>
<configuration>
<webAppConfig>
<contextPath>/magazine</contextPath>
<baseResource implementation="org.mortbay.resource.ResourceCollection">
<resourcesAsCSV>
${basedir}/src/main/webapp,
${basedir}/war
</resourcesAsCSV>
</baseResource>
</webAppConfig>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8888</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<scanIntervalSeconds>3</scanIntervalSeconds>
<scanTargets>
<scanTarget>${basedir}/war</scanTarget>
</scanTargets>
</configuration>
</plugin>
AND
For debugging I create two tasks:
1) maven build inside eclipse that runs two goals: war:exploded gwt:debug
The first one copies all the resources into war directory for gwt debug to use them.
Next the gwt is ready.
Maybe you need to execute gwt:compile for the first time
2) a Java Remote Application debug configuration, with your project selected.
You run this configuration when the gwt:debug is "listening at port 8000"
AND: this is in a parent pom.xml (sorry I'll edit this post later :)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1-alpha-2</version>
<configuration>
<warSourceDirectory>${basedir}/src/main/webapp</warSourceDirectory>
<webappDirectory>${basedir}/war</webappDirectory>
<warName>${artifactId}</warName>
</configuration>
</plugin>
helios wrote good explanation. But it's not actual at the moment. So I advice you to try my modern example of EAR application running on GlassFish and with full debug support.

Categories

Resources