Converting Maven project to EAR - java

I am new to maven.
I have created a maven project , in this i have twosession beans and i have added all dependencies in pom.xml. I want to conver this project to EARso that I can deploy it on jboss EAP 6.0 .
I have used
<plugin>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.3</version>
<configuration>
<ejbVersion>3.1</ejbVersion>
</configuration>
</plugin>
but it doen't provide the runtime dependencies.
How do i convert maven project to EAR file. How do get all dependencies including project dependencies at runtime.

I would suggest using maven-ear-plugin. The pom.xml would have the following item inside <build><plugins>..</plugins>..</build> listing:
(taken from the documentation)
<build>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.8</version>
<configuration>
<!-- configuration elements go here -->
</configuration>
</plugin>
</plugins>
</build>
Please also refer to the documentation here: http://maven.apache.org/plugins/maven-ear-plugin/usage.html.
Maven handles all the dependencies that you list in the <dependencies>...</dependencies> section that follows the above block. For example:
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
You can get the dependency details, like the above for log4j, from various maven repositories online. (http://search.maven.org/, http://mvnrepository.com/ etc.)

Related

Maven pom file, what is it doing?

I have just started using Maven, in a newbie capacity, just want to understand something around dependencies.
I am trying to build a micro web service using iText and the pdf output functionality.
So my very first steps is seeing if I can get a pdf output from a very simple Java program.
In my pom file i have the following dependencies:
<!-- iText Core -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>${itext.version}</version>
<type>pom</type>
</dependency>
<!-- iText pdfHTML add-on -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>2.1.6</version>
</dependency>
After reading the information on the Maven site, the pom file should do all of the heavy lifting in getting the dependencies, this is the bit i'm a little confused on.
Will the pom file physically download the files to the the app location on application start so that he app can utilize these files?
if that's the case it doesn't seem to be doing this and so am I missing something in the pom file to enable this?
The full pom file is:
<?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.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<name>my-app</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<itext.version>RELEASE</itext.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- iText Core -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>${itext.version}</version>
<type>pom</type>
</dependency>
<!-- iText pdfHTML add-on -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>2.1.6</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Any help appreciated.
Thanks
When maven build is executed, Maven automatically downloads all the dependency jars into the local repository.
the local repository of Maven is a folder location on the developer's machine, where all the project artifacts are stored locally.
Usually this folder is named .m2.
Here's where the default path to this folder is – based on OS:
Windows: C:\Users\User_Name\ .m2
Linux: /home/User_Name/.m2
Mac: /Users/user_name/.m2
https://www.baeldung.com/maven-local-repository
Maven does download the dependencies to the local m2 repository. But this is more meant for building the application, not for running.
What you want (copy the dependencies next to the output jar) can be achieved with the goal dependency:copy-dependencies
See this blog post:
https://technology.amis.nl/2017/02/09/download-all-directly-and-indirectly-required-jar-files-using-maven-install-dependencycopy-dependencies/
Managing dependencies is one of the key features of Maven.
Dependency management: It is possible to define dependencies to other
projects. During the build, the Maven build system resolves the
dependencies and it also builds the dependent projects if needed.
Resolving dependencies does mean it downloads all the specified jars in the local system.
The Maven tooling reads the pom file and resolves the dependencies of
the project. Maven validates if required components are available in a
local repository. The local repository is found in the .m2/repository
folder of the users home directory.
Note that .m2/ is a hidden folder. If you are using Linux, would be this path /home/someuser/.m2
Read this
If however its not downloading the jars or creating the .m2 directory at all, then either you are not building the project right or you are not connected to the internet.

Best way to build twice the same webapp with different dependencies using maven

I have a maven project with a webapp for which I need two versions, each one having its own set of dependencies. The intent is to support two different (and conflicting) versions of a storage client. The webapp code, configuration file and anything but certain libraries is the same in both cases. The right client is loaded at runtime : I just need to drop the right jar (and its dependencies) in the lib folder of the webapp.
If I deploy the dependencies manually, I lose the opportunity to check for version conflicts (which I do when I build a maven project with all its dependencies correctly set).
I do not want to deploy the webapp(s) on the maven repository since it is not a library and it only makes a big archive (mainly because of the embedded dependencies) that consumes space for nothing. Thus, to build the final wars, I cannot add a dependency on the webapp project.
I do not want to duplicate the common webapp class files and configuration files in two different modules. It would make future evolutions more difficult because of the necessary synchronization between the two modules each time one file is updated.
Any suggestion on how to solve this ?
Note that the best solution should allow to build both wars at once.
Use Maven profiles.
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
You can put certain dependencies into certain profiles and activate/deactivate them through the command line with the -P parameter.
I guess defining two profiles in your pom might do the trick :
<project [...]>
[...]
<profiles>
<profile>
<id>storage1</id>
<dependencies>
<dependency>
<groupId>my.group.storage</groupId>
<artifactId>thisOne</artifactId>
<version>13</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>storage2</id>
<dependencies>
<dependency>
<groupId>my.group.storage</groupId>
<artifactId>thisOtherOne</artifactId>
<version>37</version>
</dependency>
</dependencies>
</profile>
</profiles>
[...]
</project>
Call one or the other with mvn -P storage1 or mvn -P storage2. You can also make one active by default, use activation triggers based on other properties, etc.
Here's their introduction article.
In the end, I did not use profiles. There was an issue building both webapp versions at once.
Instead I used war overlays https://maven.apache.org/plugins/maven-war-plugin/overlays.html.
First, I created a skinny war version of the webapp. The skinny war does not include libraries nor META-INF files. Only resources like configuration files. The webapp classes are packaged in a jar (using the attachedClasses configuration option of the maven-war-plugin). I do not mind having this war deployed since it is very lightweigth. Here is the configuration of the maven-war-plugin :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<outputFileNameMapping>#{groupId}#.#{artifactId}#-#{version}##{dashClassifier?}#.#{extension}#</outputFileNameMapping>
<attachClasses>true</attachClasses>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
<packagingExcludes>WEB-INF/classes/**/*,WEB-INF/lib/*</packagingExcludes>
</configuration>
</plugin>
Then, I created 2 additional modules, one for each flavour of the webapp. In the dependencies, I set :
- the webapp as a dependency of type war
- the jar of the webapp classes
- the storage client library
That way, maven checks for dependency conflicts in all the libraries. The webapp classes are imported through the dependency. The overlay war is used to build the final war. No duplicate code between the 2 flavours of the webapp. Only the client dependency changes between the 2 pom files. Here is an excerpt of one of them :
<dependencies>
<dependency>
<groupId>com.storage</groupId>
<artifactId>client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.group.id</groupId>
<artifactId>webapp</artifactId>
<version>${project.version}</version>
<classifier>classes</classifier>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.group.id</groupId>
<artifactId>webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>

Spark related jars cannot be resolved in Eclipse

I'm new to Spark so am trying to setup a project from the book Learning Spark: Lightning-Fast Big Data Analysis. The book uses version 1.3 but I've only got 2.1.1 so am trying to work around a few differences.
All the Spark related jars that I'm importing into my Java project have a "import org.apache cannot be resolved". I know it's because the project cannot find the jar files specified.
I can manually add each by going to Build Path > Configure Build path and adding them to the Libraries section but I think I shouldn't need to do this. The project uses Maven so I believe if I have the Spark dependencies configured correctly in my pom.xml it should work. Is this correct?
I also set the following environment variables:
export SPARK_HOME=/Users/mymac/spark-2.1.1-bin-hadoop2.7/
export PATH="$SPARK_HOME/bin/:$PATH"
Are there any others I should be aware of?
Here's the contents of my pom.xml:
<project>
<groupId>com.oreilly.learningsparkexamples.mini</groupId>
<artifactId>learning-spark-mini-example</artifactId>
<modelVersion>4.0.0</modelVersion>
<name>example</name>
<packaging>jar</packaging>
<version>0.0.1</version>
<dependencies>
<dependency> <!-- Spark dependency -->
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.11.8</version>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
This should be setup as a Maven project, not a Java project. In my case to resolve deleted the project from my workspace, re-created it in the workspace as a general project, then converted it to a Maven project. I probably should have just set it up as a Maven project at the start.

Errors deploying Java + Groovy mixed code on Heroku

I'm trying to deploy a project on Heroku but I'm getting Maven compilaton errors like this:
remote: [ERROR] /tmp/build_5d64555c50abcb9638e3ef5b331a0107/src/main/java/com/davioooh/myapp/services/TestService.java:[3,43] package com.davioooh.myapp.domain does not exist
In my project I'm using both Java and Groovy classes. All Groovy classes are in com.davioooh.myapp.domain that can't be found during compilation.
I also tried to move all Groovy classe in src/main/groovy folder but it's still not working...
Is there a way to correctly deploy my application?
I finally solved adding Groovy Eclipse Maven Plugin as compiler plugin in my project pom.xml.
<build>
...
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<!-- 2.8.0-01 and later require maven-compiler-plugin 3.1 or higher -->
<version>3.1</version>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.1-01</version>
</dependency>
<!-- for 2.8.0-01 and later you must have an explicit dependency on groovy-eclipse-batch -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>2.3.7-01</version>
</dependency>
</dependencies>
</plugin>
</plugins>
...
</build>

Maven: Missing dependency when using test-jar at runtime

My Maven project foo.web has its source files in src/main and the test sources in src/test. Of course, the test classes make use of the "main" classes. Now I want to use the test classes in another project during runtime, so I followed these instructions on how to create a test-jar.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
This works perfectly well, a jar like web-SNAPSHOT-tests.jar is created and I can include it in my other project.
<dependency>
<groupId>foo</groupId>
<artifactId>web</artifactId>
<version>SNAPSHOT</version>
<type>test-jar</type>
</dependency>
But it seems like the dependency to web-SNAPSHOT is not correctly set, because at runtime I receive NoClassDefFoundErrors of classes which are available in foo.web. So I added another dependency:
<dependency>
<groupId>foo</groupId>
<artifactId>web</artifactId>
<version>SNAPSHOT</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
Unfortunately, this changes nothing. Does anyone know what is wrong here?
WAR archives are structured differently from JARs. When running in an application server such as Tomcat or JBoss, the server will handle the WAR correctly. Since you are running outside of a server, the artifact will be used like to a normal JAR archive. Because WARs use different locations for the .class files, the NoClassDefFoundError is thrown at run time.
In a JAR, the class com.example.Foo will be stored at /com/example/Foo.class. Since WARs are designed to contain libraries, resources etc. the classes should not be stored relative to the root of the archive. Instead, they are contained in the folder /WEB-INF/classes, Foo would be stored as /WEB-INF/classes/com/example/Foo.class.
Fortunately, the Maven developers thought of this issue and added the attachClasses option to the WAR plugin. This option creates an additional JAR with the classes classifier that contains only the Java classes in JAR format (relative the the archive root).
To enable the building of this JAR, you can use this snippet in your WAR project's build section (in addition to the configuration for the maven-jar-plugin to build the test JAR):
<pluginManagement>
<plugins>
<!-- … -->
<plugin>
<!-- build the classes JAR (non-test classes) -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- … -->
<plugin>
<!-- build the test JAR (test classes) -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Since the classes are attached, they will be installed and deployed by Maven together with the WAR artifact. Note that this only provides you with the contents of the regular WAR archive, to use the test classes, you need to depend on both the classes artifact and the test jar. To do this, you can use:
<dependencies>
<!-- … -->
<dependency>
<!-- test classes only -->
<groupId>foo</groupId>
<artifactId>web</artifactId>
<version>SNAPSHOT</version>
<type>test-jar</type>
</dependency>
<dependency>
<!-- non-test classes only -->
<groupId>foo</groupId>
<artifactId>web</artifactId>
<version>SNAPSHOT</version>
<type>jar</type>
<classifier>classes</classifier>
<scope>runtime</scope>
</dependency>
</dependencies>
Try:
<dependency>
<groupId>foo</groupId>
<artifactId>web</artifactId>
<version>SNAPSHOT</version>
<type>war</type>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
Maven allows you some configuration regarding snapshots dependancy
<repository>
<id>foo-repository</id>
<url>...</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>XXX</updatePolicy>
</snapshots>
Check the above config. If its false in pom.xml maven will not update snapshots. Also you will find the following thread useful for your query What exactly is a Maven Snapshot and why do we need it?

Categories

Resources