Maven war project with jars - maven

Hey I am writting a project which includes 2 other maven project:
JPA with EJB project (DAO layer) packaging .jar
Rest Services Project packaging .war
I found help with setting dependency with eclipse. In my war project I've added local project with DAOs. Compiling, building(mvn clean install on two pom.xml) went succesfull. But I can't deploy it on wildfly server. I get NoClassDef of class from my jar package.
On the other hand I saw a lot of projects with DAO packing in jar. But there are EJB3 annotations. Will they work with JEE Server in that configuration?(They don't need web.xml so maybe it is correct). Which scope i have to set of my dependent DAO project? If i have NoClassDef error it seems there is no compiled classes at runtime, or there is 2 or more definitions of classes from this package. I've tried few configurations, but I can't get solution.
Could someone write best practice to setting maven projects? For example
DAO layer type: jar
Rest Services layer type: war, dependence: DAO { scope: default, type:jar}

I think a good practice would be to define a project parent (Parent POM), which must define the module involved:
<modules>
<module>application-dao</module>
<module>application-rest</module>
</modules>
and define as a dependency, your application ".jar"
<dependency>
<groupId>com.test</groupId>
<artifactId>application-dao</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
A recommendation you could add an extra layer of management, then you would
application-dao
application-core
application-rest

Related

Managing runtime dependencies in a maven reactor project

I have a maven reactor project with a rest module and a war module. The war module is a wrapper for the rest module along with the web.xml file. I am trying to understand if it's a good practice to maintain all the runtime dependencies in war module. For instance, if I am pulling in a dependency X (which has an interface X) in the rest module, I want to pull the runtime dependency of X as part of the war module. This way all the compile scoped dependencies are in the rest layer pom and all the runtime dependencies are in the war layer.
Note: I don't see a case where the rest layer will be pulled in by any other pom file other than the war project.
Can anyone see a problem with this approach? Am I missing anything that I would regret down the road?
Example:
Project A has two modules: project-rest and project-war. Project-war is a wrapper for the project-rest and has some web filters around authentication in the web.xml (there is no source code in this module).
Project-rest obviously has REST resources and makes calls to the service layer. The service layer is divided into different projects based on the implementations, project-service is the interface and project-service-hibernate is the implementation. As far as managing dependencies in project-rest, all I need is the compile-time dependencies for the project to build. I am planning to add the project-service dependency to the project-rest pom file and project-service-hibernate as a runtime dependency on the project-war pom file. The goal here is to separate out and manage all the runtime dependencies in the war module and the compile-time dependencies in the rest module.
Actually, I would prefer to pack all the dependencies (both the runtime and the compile dependencies) into the rest module.
In this way, you see what compile and runtime dependencies belong together.
Especially, if the war has no source code, I would not add dependencies.

Use entity and repository definitions from Spring Boot outside of web application

I have a Spring Boot 2.1 web application. It works great. I can package it as either a WAR or a JAR.
In my pom.xml file I use:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
This application has many entity classes and quite a few Spring Data repositories. Almost always we deploy it as a WAR file.
Here's the question: sometimes we need to do a command line or batch process on our database. For example, we might want to run a process to resize all the images which are stored in the database, and that should be run by an administrator from the command line.
It would be great if mvn install would install a JAR file in the local Maven repository and I could use that artifact in another project to access my entity and repository definitions. I've tried many things, but whenever I build my project as a JAR file, and I look at the JAR, all my classes are within BOOT-INF/classes, which doens't allow them to be referenced from another project.
I was able to fix that by using a repackage goal in the spring-boot-maven-plugin. However, when I did that, it did generate a jar file but my CLI application couldn't start correctly with the repository beans created.
I read in the Spring Boot documentation:
Like a war file, a Spring Boot application is not intended to be used
as a dependency. If your application contains classes that you want to
share with other projects, the recommended approach is to move that
code into a separate module. The separate module can then be depended
upon by your application and other projects.
Is there any simpler way to do this, such that I don't have to create yet another project and manage that? Or is it a good practice to have a separate project for entities and Spring Data repositories?
So, in short words you just want to have a library with your entity and repositories? Then it should be enough to configure a simple maven project, a standard one, not inheriting from Spring Boot.
As spring Boot uses Spring Data JPA under the covers, you just need Spring Data JPA declarations, so add the dependency marking it as provided.
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>Some reference version<version>
<scope>provided<scope>
</dependency>
<dependencies>
This allows not to make the project include the Spring Data JPA dependency itself, as it will be included by the end project, which uses Spring Boot. However, you'll need to declare a reference version to use, you could take the one your current Spring Boot project uses (you can have a look in the maven dependency tree).
https://spring.io/projects/spring-data-jpa
Difference between maven scope compile and provided for JAR packaging

Liferay plugin package dependencies and Maven

I'm starting to develop a Spring-MVC Portlet project. I did all the configuration needed in portlet.xml and web.xml but still a little bit confused about the Spring dependencies that have been declared in liferay-plugin-package.properties. In fact, should I add the required dependencies in this file and declare them as provided in the project pom.xml?
I use Maven as the build and dependency management tool and all examples I've found are based on the ANT project.
How does Liferay is processes the dependencies declared in liferay-plugin-package.properties ?
Besides, a maven compile fails since it does not find Spring MVC libraries required for the Spring MVC portlet project. What do you think is missing (or) incorrect in the configuration to create Spring MVC portlet ?
thanks in advance
The easiest way to go about this is to use the Maven Archetype that's been provided by liferay.
The Maven dependency is:
<dependency>
<groupId>com.liferay.maven.archetypes</groupId>
<artifactId>liferay-portlet-spring-mvc-archetype</artifactId>
<version>6.2.10.15</version>
Install this archetype in your local repository and then create a Maven project from this archetype.
This will have all the prerequisites needed for your project.
It is not necessarily to put any dependencies into liferay-plugin-package.properties file. All you need for your Spring MVC Portlet project should be presented in the project pom.xml file.
All dependencies are accessible from maven repo, e.g. http://mvnrepository.com/artifact/org.springframework/spring-webmvc-portlet

IntelliJ Spring Web and Maven

I am trying a create JEE spring web project (+spring security, mvc, web flow) and it will be a maven project with IntelliJ IDE.
I tried :
1) Create Project as "Spring",
2) Additional Libraries and frameworks : Spring, Spring MVC, Spring Security, Spring Web Flow. Web Application, Application Server, Hibernate.
And click on Finish button.
3) After project created, right clicked and "Add frameworks support" and selected maven.
I have three questions :
1) Is this a right approach to create a spring web maven project with IntelliJ?
2) Project has a lib folder that has spring, hibernate jars etc. They are not included in pom.xml file as dependency. How can i make them as they defined in pom.xml file so these jars will be in "External Libraries" folder?
3) When i didn't select "Application Server" while creating a new project, I cannot add later, when the project is created using "Add frameworks support". Why?
Thanks in advance.
Is this a right approach to create a spring web maven project with
IntelliJ?
No, create a Maven (or Gradle) project form starting point and then add dependencies through Maven (or Gradle) dependency management system. Generally, managing dependencies through lib folders or System Wide Dependencies are NOT good ideas. Read more on
Project has a lib folder that has spring, hibernate jars etc. They are
not included in pom.xml file as dependency. How can i make them as
they defined in pom.xml file so these jars will be in "External
Libraries" folder?
Delete all jar files and replace them with dependency section of pom.xml. You should find groupId, artifactId and version coordiantes of each one. For example, for spring-core module, you should add this to your <dependencies></dependencies> section:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.0.RELEASE</version>
</dependency
When i didn't select "Application Server" while creating a new
project, I cannot add later, when the project is created using "Add
frameworks support". Why?
After creating project, you can add Application Servers or Servlet Containers through Run > Edit Configuration settings.

Using Seam in a single legacy WAR of an otherwise Weld-enabled EAR

We are using Wildfly 8.2.0.Final, Maven 2.2.1, Seam 2.2.0.GA, and Weld 2.2.6.Final.
We have an EAR file with a legacy WAR, a new WAR, and a bunch of other modules. The legacy WAR relies on Seam, but the new WAR and the rest of the modules in the EAR rely on Weld.
Currently, only the legacy WAR is working because we have the Weld subsystem excluded in jboss-deployment-structure.xml until we can get Seam isolated to the legacy WAR somehow. We tried to remove Seam from the EAR and move it up as a dependency of the legacy WAR, but that didn't work. To work with EJBs, it seems like it needs to be a dependency of the EAR and defined as an ejbModule in the maven-ear-plugin configuration.
Any ideas about how we can set this up?
You could try this (all happens in jboss-deployment-structure.xml):
1) Enable Weld subsystem. Basically, remove it exclusion: it's an implicit dependency, so there is no need to depend on it explicitly in any module.
2) wars should always be treated as isolated, but to be really sure you could add this:
<subsystem xmlns="urn:jboss:domain:ee:1.0" >
<ear-subdeployments-isolated>true</ear-subdeployments-isolated>
</subsystem>
3) For legacy war sub-deployment provide an explicit exclusion for Weld.
4) For all other modules provide an explicit exclusion for Seam.*
I think you've already checked it but: Class Loading in WildFly
*Update on module exclusion:
If it still provided as a module of AS, you should find it it modules/, check its' module.xml for module-name and then use exclusion like:
<exclusions>
<module name="module_name" />
</exclusions>
If you provide it in your legacy war WEB-INF/lib/, then nothing should be done I think. Or you could register it as a module manually and then exclude :)
Why not dividing into to seperate ears? After all you are using incompatible components in your war's. So one ear has exactly the same definitions as the other except from the war file. No need to dublicate any code.

Resources