Call java main method during maven package - java

I have main class which scan classpath and generates some files. I want maven to call this main method during maven package and place generated files in target directory. How to do that?

You can configure your pom.xml to run some method while executing package phase like this -
<build>
<plugins>
<plugin>
<groupId>some.group.id</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>some.package.where.your.main.Class</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
After configuring pom.xml you may run the following command -
mvn package
Now the package phase of maven life cycle will execute the main() method from the class you have mentioned in <mainClass> </mainClass>.
See some other ways at: 3 ways to run Java main from Maven

Related

Problem integrating web3j into maven clean install

I have a multi-module maven project where I want to generate java wrappers from .sol files, to achieve this I'm using web3j's maven plugin. Here are the (relevant sections of the) poms:
main pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.web3j</groupId>
<artifactId>web3j-maven-plugin</artifactId>
<version>4.9.4</version>
<executions>
<execution>
<goals>
<goal>generate-sources</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
child pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.web3j</groupId>
<artifactId>web3j-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate-sources</goal>
</goals>
</execution>
</executions>
<configuration>
<soliditySourceFiles>
<directory>${project.basedir}/src/main/resources/solidity</directory>
<includes>
<include>**/*.sol</include>
</includes>
</soliditySourceFiles>
<packageName>org.example.project-name.wrappers</packageName>
<outputDirectory>
<java>${project.build.directory}/generated-sources/web3j/java</java>
</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
I'm build the project with maven with the following command: call mvn clean -U install.
The files do generate, and in the correct location, but when maven begins the compile phase of install it runs into the following error:
Compilation failure
[ERROR] /C:/source/project/project-name/src/main/java/org/example/child/TestFile.java:[4,51]
package org.example.project-name.wrappers does not exist
TestFile is an empty file that tries to import one of the generated files.
I also have an openapi code generator plugin, it does generate files properly, and I run into no issues when importing those.
I didn't find any configuration options in the web3j plugin that I missed and I also didn't find any way to help mvn install or mvn compile consider the directory in which the wrappers are generated.
I tried manually extracting the bundled calls that install makes and manually interjecting the web3j:generate-sources:
call mvn clean
call mvn web3j:generate-sources
call mvn process-resources
call mvn compile
call mvn process-test-resources
call mvn test
call mvn package
call mvn install
call mvn deploy
But this too fails at compile. I'm assuming that the web3j plugin doesn't update a variable storing all generated sources, but that's just a guess and I don't know how I would fix that.
I managed to solve the issue using org.codehaus:build-helper-maven-plugin.
I added the plugin to the dependencies of my main pom and the relevant child (I use dependency management), then added the plugin to the child's pom:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/web3j</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
I also figured out that my assumption was correct: web3j's plugin does not update the project's sources directory.

How can I execute a plug-in, declared on parent pom.xml, on a spesific child pom.xml in Maven?

I am working on a Java EE project that consists of a parent project, and a list of sub-projects (modules). I have declared and configured a plug-in on the parent project's pom.xml within a <pluginmanagement> tag as follows:
Parent pom.xml
...
<pluginManagement>
<plugins>
<!-- inmem-db-plugin -->
<plugin>
<groupId>com.btmatthews.maven.plugins.inmemdb</groupId>
<artifactId>inmemdb-maven-plugin</artifactId>
<version>${version.inmemdb-plugin}</version>
<inherited>true</inherited>
<executions>
<execution>
<id>runDB</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
<monitorKey>inmemdb</monitorKey>
<monitorPort>11527</monitorPort>
<daemon>true</daemon>
<type>derby</type>
<database>localDB</database>
<username>${user}</username>
<password>${pass}</password>
<sources>
<script>
<sourceFile> create - data.sql </sourceFile>
<sourceFile> create - table.sql </sourceFile>
</script>
</sources>
</configuration>
</execution>
<execution>
<id>stopDB</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
...
And then I have referenced it on the child's pom.xml file:
...
<build>
<plugins>
<plugin>
<groupId>com.btmatthews.maven.plugins.inmemdb</groupId>
<artifactId>inmemdb-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
...
From what I have read on the internet, this seems to be the right way of making sure that the specific plug-in will be used only on the specific module that i have referenced it.
But, When I run the mvn install command, the plug-in that it is needed to run wont show up at all. Is there anything else that it is needed to be done, in order for the plug-in to run on a spesific module only?
Thanks in advance.
UPDATE: I replaced the wrong <phase> values with valid ones, but still when I enclose the plugin with <pluginmanagement> the plugin wont run at all.
The parent > child configuration looks correct i.e. define the plugin in pluginManagement in the parent and then engage it in the child by including it build/plugins. But this looks incorrect to me: <phase>pre-test</phase>, pre-test is not a valid phase in the Maven lifecycle and hooking your plugin up to a non existent phase will prevent it from being run. I think the correct plugin configuration is:
<plugin>
<groupId>com.btmatthews.maven.plugins.inmemdb</groupId>
<artifactId>inmemdb-maven-plugin</artifactId>
<version>${version.inmemdb-plugin}</version>
<inherited>true</inherited>
<executions>
<execution>
<id>runDB</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
...
</configuration>
</execution>
</executions>
</plugin>
I suspect you might have been using the 'phases' pre-test and post-test to start and stop the in-memory DB as/when your test phase starts and stops? If so, then the correct Maven phases are:
pre-integration-test
post-integration-test

Test the packaged artifact with Maven failsafe

In my Maven/Java project, I want to make sure that I always get the loading of resources right -- some can be always fetched as Files, others get packaged into the final .jar and have to be fetched as streams.
I now would have thought that this is the ideal task for the Maven failsafe plugin: I simply JUnit-test the affected methods in the Unit tests (means, that the tests are run using the classes lying in the classes folder) using surefire and in the integration tests (means, the tests are run using the classes packed into the jar) using surefire.
But when I make a demo project that throws an Exception when run from the .jar and doesn't when run from Eclipse, both the unit tests and the integration tests calling the method do not throw an exception, means that failsafe doesn't use the packaged jar at all.
How can I tie it to the jar artifact only?
My pom.xml:
<project ...>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>packagingTest.MainClass</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
... Dependency to JUnit ...
</project>

How to run Maven for a Java Main Method Call

I am quite new with using maven options - so sorry for an easy question.
I have asked beforehand about how to run java code (call function) and get a clear answer.. but
it seems something is wrong in this config. Or is it because I am not using a correct parameters for startup?
<build>
<plugins>
....
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>org.package.Separator.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
I am running my POM with $: mvn exec:exec
And I get such error:
One or more required plugin parameters are invalid/missing for 'exec:exec'
[0] Inside the definition for plugin 'exec-maven-plugin' specify the following:
<configuration>
...
<executable>VALUE</executable>
</configuration>
-OR-
on the command line, specify: '-Dexec.executable=VALUE'
I have read something about this error and tried originally to move the configuration to executions
secondly - specify classpath but nothing happened((
My Main function in Separator.java class is like this:
static public void main(String[] arg) throws ParserConfigurationException, TransformerException, SAXException, IOException {
//and here I call for example
System.out.println("LOL");
}
Some people use: package before goals (for previous versions) but it does not solve my issue.
I have rewrite my POM:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>org.package.Separator</mainClass>
</configuration>
</plugin>
But now Class not found exception at org.package.Separator
I am using mvn package for compile
I am running my POM with $: mvn exec:exec And I get such error:
Actually you should run
$: mvn exec:java
See example described on exec-maven-plugin:java usage.
Finnaly your plugin description should be as follows:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<id>default-cli</id>
<!--<phase>validate</phase>--> <!-- or any other phase you want. -->
<phase>integration-test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>org.package.Separator</mainClass>
</configuration>
</plugin>
Note! This plugin will work only on full name declaration in console or via phase execution:
$: mvn org.codehaus.mojo:exec-maven-plugin:1.3.2:java
$: mvn integration-test
First try renaming the classpath of your project org.package.Separator.Main
"package" is used in java namespace syntax, so don't use it in your packages classpath.
And maybe you should try adding phase to your goal like this :
...
<executions>
<execution>
<phase>run</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>org.package.Separator.Main</mainClass>
</configuration>
</execution>
</executions>
...
and execute : mvn compile run
I had the same problem. My problem was my code was NOT in src/main/java. your class containing main method must be under src/main/java

how do you write a Maven script that calls a Jar file after the code in the project is packaged?

The idea is to run "mvn package", as usual, and after all the steps are done, a Jar utility should be called passing the filepath of the packaged code (a jar or a war file) as an argument.
The utility would be called as follows from the command line:
java -jar Utility.jar -filepath {path of the new jar/war file}
I want to integrate that final step to the build process. How do I modify the pom.xml file in order to accomplish this?
have a look at the maven exec plugin. you can bind an execution of it to the package phase (would run after the built-in bindings defined by the packaging) to run java (the executable) with the arguments "-jar Utility.jar -filepath ${project.build.directory}/${project.artifactId}-${project.version}-${project.packaging}"
the result would look kinda like this:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>run jar utility</id>
<phase>package</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>java</executable>
<arguments>
<argument>-jar</argument>
<argument>Utility.jar</argument>
<argument>-filepath</argument>
<argument>${project.build.directory}/${project.build.finalName}.${project.packaging}</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
though this invocation would be platform specific. you could improve on this a bit and use "java" instead of "exec" (you'd need to provide the main class name in that Utility.jar)
if you describe what the utility you plan on using does there might be a more cross-platform way to do it (for example the maven antrun plugin)
Here's an alternative way to run the exec-maven-plugin from what #radai suggested. If you can do it this way instead, I recommend it.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<inherited>false</inherited>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<!--I don't want my project's dependencies in the classpath-->
<includeProjectDependencies>false</includeProjectDependencies>
<!--Just include the dependencies that this plugin needs. IE: the Utility dependencies-->
<includePluginDependencies>true</includePluginDependencies>
<executableDependency>
<groupId>com.utility</groupId>
<artifactId>Utility</artifactId>
</executableDependency>
<mainClass>com.utility.MyMainClass</mainClass>
<!--You may be able to use a variable substitution for pathToJarFile. Try it and see-->
<commandlineArgs>-filepath pathToJarFile</commandlineArgs>
</configuration>
<dependencies>
<dependency>
<groupId>com.utility</groupId>
<artifactId>Utility</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>

Categories