Maven compile UTF-8 & properties files - java

I am using maven to compile my project using this configuration:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>${java.version}</source>
<target>${java.version}</target>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
</plugins>
The project should be in UTF-8, but by convention .properties files should be latin1 (ISO 8859-1) and Eclipse treats them that way (I know I can change how Eclipse behaves, but that's not the point). I use .properties files for internationalization.
The problem is that, using Eclipse to deploy to Tomcat, I can see my special chars well, but when compiling through maven (for instance, through Jenkins), I get all messed characters, like somehow Maven is translating all my .properties into UTF-8, thus screwing all my i18n messages.
What is the proper way to solve this? It feels like this should be a very common problem but I haven't found a valid solution online.

Just make a supplemental entry for resources directory which contains the ISO-LATIN1 files and turn off filtering explicitly. Than those files should be kept as they are...
BTW: You should use the encoding property like:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
which is recognized by a large number of plugins for example maven-compiler-plugin, maven-resources-plugin etc.

Related

Distribute plugin resource files to host project

I have a maven plugin that exposes a Mojo, with a goal that runs at the compile stage. The project was generated using mvn archetype:generate, and the POM contains all the standard stuff that comes with running that, very little deviation. The project includes a couple of resource files, e.g. filea.txt and fileb.txt, that are packaged up as part of the jar.
When the plugin is used in a project, I'd like the files that are included in the jar to be extracted and copied to the target\test-classes directory of the host project. I'm trying to use the plugin jar to both distribute some files + expose some functionality that can then use those files.
Is this a valid approach, and if so, are there settings I can add to the plugin POM to indicate that content from the plugin should be extracted and copied? I want to centralise this logic in the plugin, rather than having to do in the plugin host.
I feel like it's something with maven-dependency-plugin or maven-resources-plugin or build-helper-maven-plugin:attach-artifact, have tried a couple of different approaches but think I'm missing something obvious:
e.g. something like this in plugin POM?
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<outputDirectory>${basedir}/target/test-classes</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>filea.txt</include>
<include>fileb.txt</include>
</includes>
</resource>
</resources>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.6.0</version>
</plugin>
// etc etc
Google fu has let me down, keep ending up on maven resources page. Can post directory structure / more information if needed.
Cheers
First I would suggest to put resources which needs to be distributed into src/main/resources which looks like you have done ...but remove the configuration for the maven-resources-plugin and let maven do it's work. This is automatically copied into target/classes/ which in result is packaged into the resulting jar later.
If your plugin needs to get those files those can accessed as a usual resource via this.getClass().getResourcesAsStream("/...") and reading and writing them into a new location preferable into target/...

How can I build maven project with foreign class names?

I'am trying to build war file for my project, that is containing russian class names. When I just run my app on development environment, it works good, but if I build that war file, all russian filenames are mangled. I cannot rename these files in the project so they could be in english. The only way out is to make my own refactoring utility for them, and run it every time these files are regenerated.
So I want to know if there is a way to make maven build it with locale specific configuration.
These files are having proper names while theq are on my filesystem. But theqy are changed when I look at them in war archive.
pom.xml snippet
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
You should always fix the encoding of source files:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
Also read the http://maven.apache.org/general.html#encoding-warning and How to configure encoding in Maven? for additional information.

Conditional inclusion of files in maven

I have a JEE6 web application project.The project structure is according to maven convention.
Now I have introduced additional web.xml files for this project.
So they are now stored in WEB-INF as below:
WEB-INF/
|__ A/web.xml
|__ B/web.xml
What is the maven way to build a war to include proper xml depending upon the property.
I know the how to add custom properties in maven.But I cannot find how to configure the maven plugin such that during the war file building it chooses the appropriate file.
Any hints/suggestions/maven best practices in such cases are most welcome.
Thanks!!
maven war plugin could be configured to add and filter some external resources. See http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html.
So I would make 2 maven profiles with 2 war plugin configuration like this :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/webapp/WEB-INF/__A</directory>
<includes>
<include>web.xml</include>
</includes>
<targetPath>WEB-INF</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
<!-- repeat for your second profile -->
BUT I think a better solution (and if your project permits it) would be to keep only one web.xml file with some filtered properties inside. In this case, you should just configure your war plugin to enable some filtering like this :
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
</configuration>
</plugin>

Compiling only selected files in Maven

I want to compile only selected files or directories (including subdirectories) within source directory. I was pretty sure I can do this using <includes> of maven-compiler-plugin's configuration, but it seems to not work as I expect since it still compiles all classes into target/classes. What is really strange, Maven output suggest that the setting actually does its work, because with:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<includes>
<include>com/example/dao/bean/*.java</include>
</includes>
</configuration>
</plugin>
I have:
[INFO] Compiling 1 source file to c:\Projects\test\target\classes
but with no compiler's configuration I have:
[INFO] Compiling 14 source file to c:\Projects\test\target\classes
In both cases however, all 14 classes are compiled into target/classes as I mentioned. Can you explain that or suggest another solution to compile only selected files?
Simple app with 3 classes.
com/company/Obj1.java
com/company/Obj2.java
com/company/inner/Obj3.java
build in pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<includes>
<include>com/company/inner/*.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
result: 1 class is compiled.
And any combination of includes is working well
or you mean something else?
I have faced a similar situation. We needed to hot swap only modified files to our remote docker container in order to improve changes-deploy time. This is how we solved it.
Add includes option in build plugin with command line argument.
Note since we wanted to add multiple files, so we have used includes and not include
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<compilerVersion>1.8</compilerVersion>
<source>1.8</source>
<target>1.8</target>
<includes>${changed.classes}</includes>
</configuration>
</plugin>
Now run compile phase with argument, example:
mvn compile -Dchanged.classes=com/demo/ClassA.java,com/demo/ClassB.java,com/demo2/*
maven-compiler-plugin using Ant-like inclusion/exclusion notation.
You can see examples in Ant documentation Ant FileSet Type
If you are want include only files from one directory, you need write it like you did:
<include>com/example/dao/bean/*.java</include>
To include also subdirectories from path, it will be:
<include>com/example/dao/bean/**/*.java</include>
I had no difficulty including or excluding files for compilation with maven compiler plugin 2.5.1. Here is the dummy project I used for the purpose. Perhaps the include pattern that you use is different.

Update Javadoc version and author across all files?

I need to keep in sync the #version tag of all class Javadocs in my project, as well as the #author tag. However I don't know an easy way to do this.
Is there a plugin (preferably a maven plugin) that could accomplish this? And no, the maven-release plugin will not do this for me.
The way I use #version is, in conjunction with #since. IMHO, I think #version represents version of software when this class was modified and #since represents the version of the software when this file/class was created.
On #author, my policy is each developer who has ever contributed to that class (in some major way) should append his/her name.
So, if you see all these processes are manual and need to be done by Class creator/modifier at the time of coding. And, obviously you will have unequal version of files. And, I guess that makes sense.
I would like to listen if someone differs on this.
Of course there's a maven way to do it, but it's very unusual:
define your src/main/java folder as <resource>, with a fixed outputDirectory. Then reconfigure javadoc and jar plugins, something like this:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<targetPath>sources</targetPath>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.6.1</version>
<configuration>
<sourcepath>${project.build.outputDirectory}/sources</sourcepath>
</configuration>
<!-- other config stripped -->
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3</version>
<configuration>
<excludes>
<exclude>sources/**</exclude>
</excludes>
</configuration>
<!-- other config stripped -->
</plugin>
</plugins>
</build>
Now you can use placeholders in your source files and interpolate them with maven properties (see maven filtering for reference)

Categories