Create Jar file using maven Plugin - java

I'm having some issues while making the JAR file which project type is pom and adding this jar in other project as dependency.
I'm using maven shaded plugins to make a JAR . It compiles well but it creates a jar file in project target directory but not in .m2 folder. Moreover, when i extract the file it doesn't have classes and resources etc
here are two projects i have
1) ProjectTestB
Project B is a independent project which have various modules like scheduler, service, web module which adds as dependency in other project
POM.XML
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>TestProjectB</groupId>
<artifactId>ProjectTestB</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>classworlds:classworlds</exclude>
<exclude>junit:junit</exclude>
<exclude>jmock:*</exclude>
<exclude>*:xml-apis</exclude>
<exclude>org.apache.maven:lib:tests</exclude>
<exclude>log4j:log4j:jar:</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<modules>
<module>scheduler</module>
</modules>
</project>
2) ProjectA
Project A contains a dependency of ProjectB and some other services and business classes. Only Project A Contains Main class which will create executable JAR file
Pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>projectA</groupId>
<artifactId>projectA</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>TestProjectB</groupId>
<artifactId>ProjectTestB</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
So the questions are
1) How to make jar which have all the classes, resources etc if project package is POM (Project B)?
2) How can i add Project B jar file in Project A class path to access it modules?

As I see you try do something strange.
Your projectB has many modules, so your projectA should has dependency to those modules. Propably module of projecB has type jar, so you can ease depend on it without doing magic with projectB

Related

JavaFX with Maven fails to import module from the same project

I have the following folder structure in a Java project:
main-module (Java module)
sub-module-to-import (Java module)
ImportedClass.java
sub-module (Java module)
fx-sub-module (JavaFX module)
- pom.xml and classes.
Whenever I import sub-module-to-import into fx-sub-module from maven, I can access ImportedClass.java after importing it in fx-sub-module's classes (instantiate the class, access its methods etc. in the IDE), but whenever I try to compile the module using mvn clean compile, I get a compilation error of type "cannot find symbol", where the symbol is a method of ImportedClass. Whenever I reload the maven project after adding the module as a dependency, everything is okay, with no XML errors or warnings, I can even ctrl + left click on sub-module-to-import's name and get sent to its pom.xml without issues. The project is a modular one, but I have removed the module-info file in order to not have to use modularity. I am using IntelliJ IDEA.
Here is the pom.xml file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>sub-module</artifactId>
<groupId>com.project</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>fx-sub-module</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.project</groupId>
<artifactId>sub-module-to-import</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>13</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>16</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<mainClass>com.project.sub-module.fx-sub-module.MainClass</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
After reading a lot about it on the internet and not managing to find a solution, I tried simple things like adding sub-module-to-import to the parent pom.xml of fx-sub-module (which is the pom.xml file of sub-module), but that didn't change anything. I also tried changing plugin/dependency versions, but this also did not help. I would really appreciate any help and will be quick to answer for further clarification on the question. Thanks in advance.
Ensure:
mvn install has been run on the sub-module-to-import maven module.
The Idea project has been synchronized with the maven project after that.

import own .jar file as dependency via Maven and have install discover and retrieve it's dependencies

So this is probably a stupid question, but I have created an own library "testlib" which I want to include in other of my own Maven projects.
This is my own librarys .pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.testlib</groupId>
<artifactId>testlib</artifactId>
<version>1.0-SNAPSHOT</version>
<name>${project.groupId}:${project.artifactId}</name>
<description>testlibrary</description>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
In order to include my library in another new project, I have created a local repository in my new projects .pom
...
<repositories>
<repository>
<id>data-local</id>
<name>data</name>
<url>file://${project.basedir}/repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.test.testlib</groupId>
<artifactId>testlib</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
...
Installing my own library "testlib" via mvn install is working fine for testlib itself. The problem is, that Maven will not detect that "testlib" requires org.slf4j, hence won't get it when I run install.
I have checked other dependencies in my .m2 folder and saw they have a .pom file with the same name as the .jar (for log4j that'd be log4j-1.2.17.pom). I tried copying testlibs .pom next to its .jar and changed the name accordinly, but that doesn't do it.
What do I have to do in order to get the same functionality as any other library from maven central? In other words, I don't want a fat .jar that has all dependencies included. I want a Maven project that adds my library as a dependency to discover that it needs sl4j and include it when mvn install is run.

Create jar A without dependencies and make dependent project C download the dependency B that this dependency A depends on

I have successfully created jar A that does not contain dependencies. This jar A depends on Jar B. I don't want to create a fat jar. I just want dependent project (lets call it C) to add my jar A as dependency, and as soon as jar A is added, project should pull in jar B.
Is this possible?
Question ends here. Below is just what I have tried so far:
What I have done:
I created Fat Jars first with both maven and gradle. Now this has all the dependencies, but my own classes are buried somewhere inside. And dependent project cannot find my classes.
Then I created a jar that does not contain any dependency. I created them separately with maven and gradle. This resolved my classes not being found issue. But then I ran into another issue. As soon as I run the project, it complains that jar B is missing. Rightfully so, as I never included it.
I will just show you my pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>custom-spring-boot-starter</groupId>
<artifactId>custom-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<scope>provided</scope>
</dependency>
<dependency> //THIS IS WHAT DEPENDENT PROJECT WILL NOT HAVE.
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus</artifactId>
<version>0.9.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>10</release>
</configuration>
</plugin>
</plugins>
</build>
This created a jar without dependencies. I added it to dependent project C. But it is complaining that it cannot find dependent B (azure-servicebus in my example). I was hoping that because pom.xml file is present in the jar file, dependent project will download another dependency automatically.
Then I rewrote my pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>custom-spring-boot-starter</groupId>
<artifactId>custom-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>10</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus</artifactId>
<version>0.9.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>10</release>
</configuration>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<executions>
<execution>
<id></id>
<goals>
<goal>revision</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
<configuration>
<dateFormat>yyyy-MM-dd-HH:mm:ss</dateFormat>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
<prefix>git</prefix>
<verbose>false</verbose>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
<format>json</format>
<gitDescribe>
<skip>false</skip>
<always>false</always>
<dirty>-dirty</dirty>
</gitDescribe>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Build-Jdk>${java.version} (${java.vendor} ${java.vm.version})</Build-Jdk>
<Digital-Voltage-Library-Version>${project.version}</Digital-Voltage-Library-Version>
<Build-Timestamp>${git.build.time}</Build-Timestamp>
<Build-Revision>${git.commit.id}</Build-Revision>
<Build-OS>${os.name} ${os.arch} ${os.version}</Build-OS>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
This is the stacktrace of the error:
Caused by: java.lang.ClassNotFoundException: com.microsoft.windowsazure.services.servicebus.ServiceBusContract
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:374)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:275)
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.getReturnType(OnBeanCondition.java:505)
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.addDeducedBeanTypeForBeanMethod(OnBeanCondition.java:491)
... 22 common frames omitted
This error easily goes away if I add azure-servicebus dependency to target project. But I don't want to do that. I want the dependency to pull in azure-servicebus.
This is how I am pulling in my jar A into project C.
compile fileTree(dir: '/lib', include: 'custom-spring-boot-starter-0.0.1-SNAPSHOT.jar')
Yes, if A has a Maven dependency on B, then B is automatically pulled when C depends on A. This is the Maven transitive dependency resolution.
Note that this has nothing to do with fat jars. B is not included in A, it is just mentioned as dependency in the POM of A.
I asked this question without knowing something very important.
When jars are put into artifactory, a corresponding .pom file also has to be placed alongside it (outside of the directory, just look at below link to understand directory structure). This pom file is what tells the dependent project that the jar you are dependent upon, requires so and so dependencies itself.
If you do mvn clean install, it automatically installs jar file and pom file at the correct location for you in your local maven repository.
This answer helped me understand:
https://stackoverflow.com/a/50002072/4828463
Thanks to everyone who tried.

Maven ear project with ejb and war modules

im working on a web application with maven and Jboss 7 wich conatins 3 modules ejb ear and war so the war will have the ejb as dependancy and the ejb will be in the same time a module of the ear so when i do this i get the same ejb twice this tree
ear
...Mywar
........Myejb
...Myejb
is this structure is correct or i should change another
the pom.xml for the war :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>tn.war.ep</groupId>
<artifactId>businessModule</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
.....
<dependency>
<groupId>tn.linckia.epgp</groupId>
<artifactId>ejbModule</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>ejb</type>
</dependency>
</dependencies>
</project>
the pom.xml for the ear :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>tn.war.ep</groupId>
<artifactId>earModule</artifactId>
<version>0.0.1</version>
<packaging>ear</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.6</version>
<configuration>
<modules>
<webModule>
<groupId>tn.war.ep</groupId>
<artifactId>businessModule</artifactId>
<bundleFileName>businessModule.war</bundleFileName>
<contextRoot>/businessModule</contextRoot>
</webModule>
<ejbModule>
<groupId>tn.war.ep</groupId>
<artifactId>ejbModule</artifactId>
<bundleFileName>ejbModule.jar</bundleFileName>
</ejbModule>
</modules>
<displayName>Security</displayName>
</configuration>
</plugin>
</plugins>
<finalName>AuthModule</finalName>
</build>
<dependencies>
<dependency>
<groupId>tn.war.ep</groupId>
<artifactId>businessModule</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>tn.war.ep</groupId>
<artifactId>ejbModule</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>ejb</type>
</dependency>
</dependencies>
</project>
Right way to configure EAR Module is to have the EJB jar dependency with "provided" scope in WAR module and having EJB jar directly under EAR like the below:
EAR
|
|-lib/someutil.jar
|-EJB.jar
|-my-web.war
| |-WEB_INF/lib
| |-coolutil.jar
|-EJB2.jar
But the my-web.war can dependent on the any EJB.jar, but its resolved in runtime by container. So, mark that ejb dependency as "provided" (by container) in WAR's pom.xml.
Option : #1
Yon don't even need a ear.
You can just put all your EJBs as jars inside the war.
Just add the EJB projects as dependencies in your War project.
Option : #2
If you still want EAR. All EJB projects output should be jars. And web project output should be war. And at last these EJB jars and web war would be placed in one EAR. This is a old fashion way, to keep it simple you could follow the method which I explained above in Option #1.
I had this issue and changing the ejb packaging tag from ejb to jar in the ejb modules pom.xml fixed the issue. No idea why!

maven 3 interproject depedency with war packaging

I have Eclipse Indigo and M2E plugin installed.
So essentially I have a standard maven web project (let's call it proj-service) that is built into a war file in the package phase. This all works fine. My issue comes in when I have my other project (lets call it proj1) that needs to use classes from proj-service. I know that this is possible in maven+eclipse but it does not seem to be working at the moment. I have the following in proj1's pom right now:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.foo</groupId>
<artifactId>proj1</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>proj1</name>
<properties>
<spring.version>3.1.0.RELEASE</spring.version>
</properties>
<dependencies>
<!-- Maven Repo Libraries -->
.........
<!-- Interproject dependencies -->
<dependency>
<groupId>com.mycompany.foo</groupId>
<artifactId>proj-service</artifactId>
<version>1.0</version>
<type>war</type>
</dependency>
</dependencies>
<build>
<finalName>lsoap</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Unfortunately with Maven's war packaging you can't reuse classes from war project, because there is no direct build artifact you can use for the class path.
So, in order to do share classes properly you need to extract those common classes into a 3rd common project (jar packaging) and make it as dependency in both of your other projects.
First you have to change the configuration of your proj-service project in the way to change the configuration of the maven-war-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<attachClasses>true</attachClasses>
<archiveClasses>true</archiveClasses>
...
</configuration>
</plugin>
This will it make possible to use the classes from the proj-service project in other projects via the following dependencies:
<dependency>
<groupId>myGroup</groupId>
<artifactId>myArtifact</artifactId>
<version>myVersion</myVersion>
<classifier>classes</classifier>
</dependency>
This will result in changing your dependency from:
<dependency>
<groupId>com.mycompany.foo</groupId>
<artifactId>proj-service</artifactId>
<version>1.0</version>
<type>war</type>
</dependency>
into:
<dependency>
<groupId>com.mycompany.foo</groupId>
<artifactId>proj-service</artifactId>
<version>1.0</version>
<classifier>classes</classifier/>
</dependency>

Categories

Resources