Can maven change package declarations when compiling a project? - java

Well, I have googled this topic many times and I haven't found an answer yet: Can maven change the package declarations right before compiling a project?
My objective is have project A, which is an API, all in one package, and each project B and C will use the same dependency on eclipse. My objective is that once maven is about to compile the project, the package declarations get changed to that project's specific package and then it compiles the project.
This is useful because I have many projects using the same API and I keep making changes to the API itself to suit my needs, but it's a pain to have to go trough every project and change it all again.
If you have any idea how to do this, and, more importantly, if it is possible, let me know please. Thanks in advance!

Google's maven replacer plugin can do such things, it can edit your java files at build time. I have used it for silencing warnings in automatically generated java files. It can definitely be used for even more evil things.
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>src/main/java/mycodegen/**/*.java</include>
</includes>
<regex>true</regex>
<regexFlags>
<regexFlag>MULTILINE</regexFlag>
</regexFlags>
<replacements>
<replacement>
<token>^public class</token>
<value>#SuppressWarnings("all") public class</value>
</replacement>
</replacements>
</configuration>
</plugin>
This is what I had used. It should be very similar to change package declarations in Java files. By now there should be much newer versions of the plugin.

Related

Customized build lifecycle for Java project

Working on one Maven project, I faced quite a curious kind of dependencies cycle: there are two maven modules, one of which is instrumenting the Java bytecode, and at the same time uses assertions (for unit-testing purposes), defined in another module, which is in turn supposed to be instrumented by the first one.
So, it's not just a cycle, it's cycle, spreaded between maven phases. I failed to solve it by means of reorganizing Maven modules, and I doubt that it is possible in such case.
Hypothetical solution for this problem might be to reorganise build lifecycle in a following way:
Compile the first module's sources
Compile the second module's sources
Instrument the second module using the 1st module's classes
Test first and second modules
Package them
Install/deploy them
I doubt that Maven was designed for such hacks. What about other tools? Can it be done with Gradle or Ivy? Or maybe it is possible in Maven by some plugin? Or probably the problem is typical and has more straight solution?
PS: please do not suggest to outline common dependencies to a separate module. If it was so simple, I wouldn't be here.
In my opinion you should look on Gradle for this task, specifically to it's multi-project builds. Gradle allows to access tasks from any project of multi-project build from any build script. Therefore, you should define tasks you need in subprojects and call them from the root project in any order you want.
Gradle proposal was really good, but was not applicable in my case due to internal obstacles.
For Maven, I just had to admit that separating the instrumentation code and test assertions to modules is not possible in my case: they are too coupled at build time. So, instead of trying to separate them at build time, I managed to separate them afterwards.
Note that this solution is not nice way of doing stuff: you may get class loading exceptions at runtime if the classes you are trying to separate are actually using each other. Also, there won't be any transitive resolution between the separated jars - Maven will treat them as completely independent.
So, I managed to get instrumentation code and test assertions separated to two jar artifacts by following this step sequence:
Let them both be in one Maven module.
Do compilation and instrumentation on the module's build phase and testing on test phase as usual. It is no more the problem since all the nesessary stuff for this phases is located right in the module.
At package phase, configure maven jar plugin to collect additional artifacts with limited set of class files.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>jar-api</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>api</classifier>
<includes>
<include>com/example/api/**</include>
</includes>
</configuration>
</execution>
<execution>
<id>jar-codegen</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>codegen</classifier>
<skipIfEmpty>false</skipIfEmpty>
<includes>
<include>oo/example/codegen/**</include>
</includes>
</configuration>
</execution>
<execution>
<id>jar-tests</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<skipIfEmpty>false</skipIfEmpty>
<classifier>tests</classifier>
<includes>
<include>com/example/tests/**</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
At install phase, these additional artifacts will be installed to local repository together with the assembled module.

How to reference dependencies in license documentation

I'm working on a commercial project which uses many open source libraries as its foundation. It's a Java project and we use maven to resolve dependencies. This is great but ... the companies to whom we want to sell our software are traditionally conservative about what they allow to run on site and will want a full inventory of all third party libraries used. Now I can get the list by looking at our project's pom files to find our first order dependencies and then I suppose use the magic of maven to trace all the transitive dependencies. It will be a long list however and one which is likely to change as we move from version to version of any of the third party packages.
Is there an established approach to documenting this kind of dependency tree?
Is there an accepted "lawyer friendly" form of describing software dependencies that I should be adopting?
Any suggestions would be most welcome!
Cheers
Rich
http://maven.apache.org/plugins/maven-project-info-reports-plugin/license-mojo.html
(a part of http://maven.apache.org/plugins/maven-project-info-reports-plugin/_ )
and
Use license-check-maven-plugin
<build>
<plugins>
<plugin>
<groupId>org.complykit</groupId>
<artifactId>license-check-maven-plugin</artifactId>
<version>0.5.3</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>os-check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Reference: https://github.com/mrice/license-check

Maven: Replace token in source file before compilation

I want to replace a token #NAME# in a source file (in my case *.java) before compilation.
I try to use google replacer plugin but I am open for anything which will help me.
1.pom.xml
The pom file look like this
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>src/main/java/com/test/sample/File.java</include>
</includes>
<replacements>
<replacement>
<token>#NAME#</token>
<value>New content</value>
</replacement>
</replacements>
</configuration>
</plugin>
But after I run mvn package the output is:
--- replacer:1.5.3:replace (default) # MyProject --- [INFO] Replacement run on 0 file.
Because there is no error I do not know what I have done wrong.
Maybe:
Defined phase is wrong
Defined include is wrong
...
Greetings!
I think there are two options.
If you keep using the plugin I think you need to add the ${basedir} to the include statement:
<include>${basedir}/src/main/java/com/test/sample/File.java</include>
If you dont want to modify the file in src/main but filter the file and add that one to the build you can use the standard resource filtering and the buildhelper plugin to add those "generated sources" to the build.
So step one would be using resource filtering to copy the file: http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
And then use the http://www.mojohaus.org/build-helper-maven-plugin/ to add those sources to the build.
Some IDEs (IntelliJ) will recognize /target/genereated-sources automatically if you keep using that folder (its not standard but very common). If you search for "maven" and "generated-sources" you will find quite some tutorials.
Hope this helps :)
While this is something you usually should not do in the first place, sometimes you have no choice (in my case it was "converting" an old project to Maven with changing as little of the code as possible). The above somehow did not work (while I could replace a placeholder in the source file and add the generated-sources folder to be compiled, it complained about duplicate source files).
Then I found an easier way by using the templating-maven-plugin as described here http://www.mojohaus.org/templating-maven-plugin/examples/source-filtering.html:
Put the file with the placeholder in the folder /src/main/java-templates. Excerpt from my source code:
public static final String APPLICATION_VERSION = "r${project.version}";
Add the following to your pom's plugins section:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>filter-src</id>
<goals>
<goal>filter-sources</goal>
</goals>
</execution>
</executions>
</plugin>

build-helper-maven-plugin adding additional source

I am trying to add an additional source folder to my current maven project by using build-helper-maven plugin.
This source folder contains some common classes, like utility classes.
For that, here is my relevant pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>C:/Users/CommonIncludes/src</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Eclipse is showing the following error :
Build path entry is missing.
Project->Right Click->Java build path->Source->
Project/Users/CommonIncludes/src(missing)
Here the additional source location : "C:/Users/CommonIncludes/src" is outside of the workspace of the current project. But eclipse always treating this as a location from current project.
I am using Eclipse 4.3 and m2e.
How can I overcome this error through MAVEN, so that Eclipse can identify the linked source from correct location.? Or is there any alternate way to do this using MAVEN?
Any help will be greatly appreciated. Thanks in advance.
Found it in an alternate way..works great.!
Steps include
1. Removed build-helper-maven-plugin from pom .
2. Created another maven project and added the common classes in it. Added maven-source-plugin in this pom to generate sources.
3. To the same pom, added maven-dependency-plugin to copy this generated sources to the desired location (My project's src/main/java).
4. Run a maven build for common classes project.
Now the common code in my project. Thanks.
I had a lot of inconsistent trouble with this plugin.
by far the simplest workaround in my case was simply to apply the addition via the standard 'resources' options.
hope this helps someone.
<build>
<resources>
...
<resource>
<directory>${project.build.directory}/generated-sources</directory>
<targetPath>${project.build.outputDirectory}</targetPath>
</resource>
</build>

How to check project boundaries access in Maven projects

I have a set of Maven projects and I'd like to define access rules.
For example, projects Database and Cache may only be accessed by project DataLayer, but not from project UiLayer. I'm speaking in terms of maven projects, but a package level access verification may also work, as long as it's easy to integrate into maven projects.
I've looked at Macker, which has a nice set of features such as access control b/w java packages, style checking etc, but have been having hard time tying that into a set of maven projects.
There's the macker-maven-plugin, which is still under development, and I've been able to make it work for me, but I'm afraid it's not going to serve me well.
This plugin runs verifications on all project's classes.
This means that I'll have to have macker-rules.xml defining access rules in each and every maven project from now on in order to make sure rules are not broken. This looks like a maintenance nightmare.
So - did I miss something with usage of macker-maven-plugin? Perhaps I'm not using it correctly.
I have no experience with JDepend, but from short reading it looks like the thin version of macker. There is a jDepend maven plugin, but it's functionality is merely generating reports about usage and statistics, but what I really need is something else, an access check which fails the build if it fails.
Can someone suggest a better alternative for project access checks or package access checks for maven projects?
Thanks
I think you are looking for banned dependencies from maven-enforcer-plugin.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>enforce-banned-dependencies</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<excludes>
<exclude>org.apache.maven</exclude>
<exclude>org.apache.maven:badArtifact</exclude>
<exclude>*:badArtifact</exclude>
</excludes>
<includes>
<!--only 1.0 of badArtifact is allowed-->
<include>org.apache.maven:badArtifact:1.0</include>
</includes>
</bannedDependencies>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
If you split your Maven project into subprojects and structure the APIs right, it might be possible to implement your access constraints as a side-effect of the subproject dependencies.

Categories

Resources