Perform additional tasks within a maven build - java

I am wondering about how to perform specific tasks during a maven build: I would like to use some of my code to do some preprocessing on the data that I am shipping in the resulting jar. Generally given some input.xml in src/main/resources I would like to be able to call a java function / main method to obtain a file output.xml which is included available as a resource (and probably placed in target/classes/...). Using Makefiles this would correspond to an additional rule, I guess this could be done with an ant task as well (though I have never used ant myself). can I add such a rule to a maven project as well?

You can use the Maven Exec Plugin to run arbitrary Java code during your build.
If you should happen to have your tasks formulated as Ant targets, the Maven Antrun Plugin can be used to run those.

Related

Run tests with multiple dependency versions?

My library depends on another library; let's call it "lib". I want to test my library with multiple versions of lib, in an automated manner.
Test if my library compiles for each version of lib.
Run JUnit 5 tests for each version of lib.
Are there any existing solutions for this?
I could write a script that changes the version number of lib in my pom.xml and executes mvn compile and mvn surefire:test. I could also use profiles and automate this with a script. I was hoping there is a better way, through something like a Maven plugin.
Maven focuses on reproducible builds which means that if you repeat the build at a later date you should get the same results which in turn requires that the dependency versions are fixed.
This fundamental mindset is what you want to challenge. Maven won't like it even if it is for a good reason, and you will most likely need to have a separate full run for each version instead of looping inside Maven.
I was thinking that the way I would approach this, is to have a bill-of-materials POM that has a dependencyManagement section that lists the exact version you want to have, which is generated in the local filesystem before each run, and then orchestrate a run for each version you want to test.
You can also leverage your build system and have a repository which orchestrates this. Github Actions can do array builds which might be what you need.

Gradle: Multiproject build - How to determine projects that need a rebuild?

I have a multi project build setup. If I execute the "jar" task of any subproject, gradle checks whether it needs to rebuild a certain dependent project or not by using the org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.
Is there a way to access this information to like build a custom task or a task in a custom plugin which automatically copies the jars of theses projects to somewhere?
You should be able to use jar.didWork to determine whether the task jar actually did some work or not if I remember correctly: https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html#getDidWork()
Or maybe more appropriate, use something like the following:
gradle.taskGraph.afterTask { task, state ->
// check anything on Task or TaskState, like didWork, executed, failure, noSource, skipMessage, skipped or upToDate
}

Including .jar files in Github for consistency

I am new to using github and have been trying to figure out this question by looking at other people's repositories, but I cannot figure it out. When people fork/clone repositories in github to their local computers to develop on the project, is it expected that the cloned project is complete (ie. it has all of the files that it needs to run properly). For example, if I were to use a third-party library in the form of a .jar file, should I include that .jar file in the repository so that my code is ready to run when someone clones it, or is it better to just make a note that you are using such-and-such third-party libraries and the user will need to download those libraries elsewhere before they begin work. I am just trying to figure at the best practices for my code commits.
Thanks!
Basically it is as Chris said.
You should use a build system that has a package manager. This way you specify which dependencies you need and it downloads them automatically. Personally I have worked with maven and ant. So, here is my experience:
Apache Maven:
First word about maven, it is not a package manager. It is a build system. It just includes a package manager, because for java folks downloading the dependencies is part of the build process.
Maven comes with a nice set of defaults. This means you just use the archtype plugin to create a project ("mvn archetype:create" on the cli). Think of an archetype as a template for your project. You can choose what ever archetype suits your needs best. In case you use some framework, there is probably an archetype for it. Otherwise the simple-project archetype will be your choice. Afterwards your code goes to src/main/java, your test cases go to src/test/java and "mvn install" will build everything. Dependencies can be added to the pom in maven's dependency format. http://search.maven.org/ is the place to look for dependencies. If you find it there, you can simply copy the xml snippet to your pom.xml (which has been created by maven's archetype system for you).
In my experience, maven is the fastest way to get a project with dependencies and test execution set up. Also I never experienced that a maven build which worked on my machine failed somewhere else (except for computers which had year-old java versions). The charm is that maven's default lifecycle (or build cycle) covers all your needs. Also there are a lot of plugins for almost everything. However, you have a big problem if you want to do something that is not covered by maven's lifecycle. However, I only ever encountered that in mixed-language projects. As soon as you need anything but java, you're screwed.
Apache Ivy:
I've only ever used it together with Apache Ant. However, Ivy is a package manager, ant provides a build system. Ivy is integrated into ant as a plugin. While maven usually works out of the box, Ant requires you to write your build file manually. This allows for greater flexibility than maven, but comes with the prize of yet another file to write and maintain. Basically Ant files are as complicated as any source code, which means you should comment and document them. Otherwise you will not be able to maintain your build process later on.
Ivy itself is as easy as maven's dependency system. You have an xml file which defines your dependencies. As for maven, you can find the appropriate xml snippets on maven central http://search.maven.org/.
As a summary, I recommend Maven in case you have a simple Java Project. Ant is for cases where you need to do something special in your build.

Do i have a chance to run a user defined program to generate resource?

I have a war project with maven ,
And I wonder if there is a plugin OR such a mechanism to generate resources at compile time so that I can minify CSS or minify JS or generate CSS-sprite ?
I think this should be a very nice plugin.
I've not used it myself, but the invoker plugin appears to be what you need. It gives you the ability to run scripts pre and post-build. For your case, just use a pre-build script to run whatever utility you need.

Using SVN with CruiseControl?

I'm trying to use CruiseControl 2.7.3, (the original), to build a Java project that is in an SVN repository.
My cruise configuration is using the svn plugin for the modification set. When a modification is detected, a build is scheduled using Ant. That Ant build file then uses the svnant Ant Task to do a complete checkout of the project. For a while, we had this set to just checkout "HEAD", but we've had cases where the build won't fire for a check in or two because the checkin occurred after the modification set check, but before the ant call to svn checkout. As a result, we are trying to change the ant build file to use the revision number that the modification check retrieves.
The CruiseControl Configuration Reference page claims that a property, svnrevision, is set and passed to the builders, just like the label property is by the labelincrementers. It appears to not be set when I press the force build button.
Is there something I need to do to make this go?
Looking at the code for the SVN source control it seems that svnrevision should be passed along to the builder, and thus along to your Ant invocation. Have you tried using the property from your Ant script?
In response to the question in the comment:
That's because in the force build case there was no modification, so there's no modification revision number. In that case the svnlabelincrementer will pass the latest revision number for what you have locally, which will also be the latest.
The cruisecontrol ant invocation has nothing to do with the (svn)label that is contructed as such. The svn label is used to annotate the build-names whereas the build.log is really just the output from ant as it is passed through cruisecontrol.
If you would like to have the revision number written to the ant build output, there are basically two ways:
One way is to have ant interact with svn in some way. Svn in ant is only available through a contrib ant task from tigris, so it is not trivial to put into your ant file. But with this in your build, you could do a svn info and get the revision number as ant properties at your disposal.
Another way is to use the svnlabelincrementer to assign the revision number to the label, and pass that onto the ant script using the buildproperties that are passed from cruisecontrol to the build scripts. As Jay mentioned in the comments, the label contains only the last successfull build revision, which is not what he wants. A fix has been proposed on this blog, but doing the work in the ant build file seems more suitable.
Can you use the quietperiod setting? After a commit, CruiseControl can wait for some amount of time (say, 30 seconds) before kicking off a build.
It won't fire off individual builds for each commit. Rather, commits around the same time will kick off a single build.

Categories