CDI error: Ambiguous dependencies trying to inject EntityManager - jboss7.x

I'm facing a strange error while trying to deploy my EJB 3.1 application in a JBoss 7.1.1 application server: WELD-001409 Ambiguous dependencies for type [EntityManager] with qualifiers [#Default] at injection point [[parameter 1] of [constructor] #Inject public br.com.sigga.siot.dao.masterdata.impl.ProfileDAOImpl(EntityManager)]. Possible dependencies [[Resource Producer Field [EntityManager] with qualifiers [#Any #Default] declared as [[field] #PersistenceContext #Produces private br.com.sigga.siot.cdi.JPAProducer.entityManager], Resource Producer Field [EntityManager] with qualifiers [#Any #Default] declared as [[field] #PersistenceContext #Produces private br.com.sigga.siot.cdi.JPAProducer.entityManager]]]
As you can see, the "possible dependencies" points twice to the same EntityManager producer: br.com.sigga.siot.cdi.JPAProducer.entityManager. This field is declared as follows:
#PersistenceContext(unitName = "siotMobility")
#Produces
private EntityManager entityManager;
A similar case was related in WELD-001409 Ambiguous dependencies but I cannot change my application server to Glassfish 4.1. :-)
My development environment: Eclipse Luna, Java 7, Maven 3.x (eclipse's embedded version). I have one Maven project (siot-mobility) with 3 modules (siot-mobility-[ear|ejb|web]).
The EAR module's POM declares the following dependencies:
<dependencies>
<dependency>
<groupId>br.com.sigga</groupId>
<artifactId>siot-mobility-web</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>br.com.sigga</groupId>
<artifactId>siot-mobility-ejb</artifactId>
<version>${project.version}</version>
<type>ejb</type>
</dependency>
</dependencies>
Maven EAR plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<version>6</version>
<defaultLibBundleDir>lib</defaultLibBundleDir>
<modules>
<webModule>
<groupId>br.com.sigga</groupId>
<artifactId>siot-mobility-web</artifactId>
</webModule>
<ejbModule>
<groupId>br.com.sigga</groupId>
<artifactId>siot-mobility-ejb</artifactId>
</ejbModule>
</modules>
</configuration>
</plugin>
Feel free to ask me about any more info that could help you help me. :-) Thanks in advance.

Error found: the EJB module was present twice in the generated EAR, once on the root path of the EAR file and a second time in the WEB-INF/lib folder of the WAR file.
I changed the dependency declaration in the WAR project's POM file from:
<dependency>
<groupId>br.com.sigga</groupId>
<artifactId>siot-mobility-ejb</artifactId>
</dependency>
to:
<dependency>
<groupId>br.com.sigga</groupId>
<artifactId>siot-mobility-ejb</artifactId>
<scope>provided</scope>
</dependency>
This way, the EJB module is not copied to the WEB-INF/lib folder of the WAR file and I have only one EntityManager producer in the generated EAR file.

Related

Using MaterialFX in IntelliJ

I've been trying to use MaterialFX (which is a JavaFX design library (like jFoenix)) in IntelliJ but I didn't succeed to do so. I've added the required dependency:
Also, I've added the requires org.glavo.materialfx.adapter; in module-info.java:
module org.example {
requires javafx.controls;
requires javafx.fxml;
requires com.jfoenix;
requires org.glavo.materialfx.adapter;
opens org.example to javafx.fxml;
exports org.example;
}
Does anyone have an idea how can I use this library because the author didn't really explain well how to do so. I would like to mention that it works perfectly in Scene Builder's latest version so I just wonder why it doesn't do so in IntelliJ.
Use Maven (or Gradle) for dependency management
You are using Maven (at least that is what the screenshot shows in Idea, though it could be Gradle making use of a Maven repository).
You should define the dependency as a maven dependency in your pom.xml (or build.gradle) then reimport the build file into Idea.
You should not manually set library dependencies in Idea.
Idea and Maven will recognize that you have a modular project and, when you have the dependency defined in Maven, they will automatically put the new dependent module on the modulepath for compilation and execution.
The maven artifact can be found by searching the maven repository:
https://search.maven.org/artifact/io.github.palexdev/materialfx/11.13.5/jar
The dependency info is:
<dependency>
<groupId>io.github.palexdev</groupId>
<artifactId>materialfx</artifactId>
<version>11.13.5</version>
</dependency>
The module-info for MaterialsFX requires VirtualizedFX. The VirtualizedFX module also needs to be on your module path. The pom.xml file for MaterialsFX has a includes a dependency on io.github.palexdev:virtualizedfx:11.2.6. So the dependent module will be accessible for your build and runtime automatically via Mavan and Idea's inbuilt integration with the Java Platform Module System.
Require the correct module name
The module name for the library is not org.glavo.materialfx.adapter, it is MaterialFX, so you should use:
requires MaterialFX;
NOT:
requires org.glavo.materialfx.adapter;
I recommend that you spend some time studying tutorials for your build tool and the Java Platform Module System.
Example app
Example was created by running the idea new JavaFX project wizard, then modifying the resultant project.
pom.xml
In addition to having a dependency for the MaterialFX library, you also need to have dependencies for both javafx-controls and javafx-fxml.
MaterialFX requires both of these transitively at build and runtime (even if you don't use fxml in your application).
The MaterialFX pom.xml does not have an explicit dependency configuration for JavaFX, so you need to define those dependencies in your project pom.xml (which you would want to do in any case to ensure that your application is using a specific JavaFX version).
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>material</artifactId>
<version>1.0-SNAPSHOT</version>
<name>material</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>18</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>18</version>
</dependency>
<dependency>
<groupId>io.github.palexdev</groupId>
<artifactId>materialfx</artifactId>
<version>11.13.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
<configuration>
<source>18</source>
<target>18</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
module-info.java
module com.example.material {
requires MaterialFX;
exports com.example.material;
}
MaterialApplication.java
package com.example.material;
import io.github.palexdev.materialfx.controls.MFXButton;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MaterialApplication extends Application {
#Override
public void start(Stage stage) {
stage.setScene(new Scene(new MFXButton("mfx")));
stage.show();
}
public static void main(String[] args) {
launch();
}
}

How to use httpclient 4.1.x with Maven

httpclient version 4.0 works in my pom.xml:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0</version>
</dependency>
...but versions > 4.0 don't compile:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.1</version>
</dependency>
The error:
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error building POM (may not be this project's POM).
Project ID: unknown:httpclient
Reason: Parent: null:httpmime:jar:null of project: unknown:httpclient has wrong
packaging: jar. Must be 'pom'. for project unknown:httpclient
Any idea how to use httpclient 4.1 with Maven?
confirmed, use Maven 3.0.x and it works! here is example from working pom.xml
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.2</version>
</dependency>
</dependencies>
I just tried same configurations
jar got downloaded from following location which is one of default repos
http://repo1.maven.org/maven2/org/apache/httpcomponents/httpcomponents-client/4.1
Just try after mentioning http://repo1.maven.org/maven2 explicitly in your pom file
and try using command line
and apache http client 4.1.1 version is also available now
It was a Maven issue: Using Maven 3.0.3 instead of 2.2.1 solved the problem.

Maven2: dependency set to compile not added to war

I have a multi module project consisting of several jar modules and a war module. When I do mvn package, the war is created but one dependency (javax.mail) is not included in the lib folder of the war.
The dependency is set to compile is the main pom. The war is not dependent from the mail.jar but a module.jar is.
When I do mvn dependency:tree, the three looks fine to me. Running in debug does not show me anything wrong either.
Anyone has an idea?
BB
Peter
Edit: in the master POM I have
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.1</version>
<scope>compile</scope>
</dependency>
as a managed dependency. The module jar has the dependency as follows:
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</dependency>
The war module has no dependency to javax.mail.
Edit2:
I do override the war plugin in the master pom like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<warName>${war.name}</warName>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
Does your pom or master pom override the maven-war-plugin? It's possible to explicitly exclude artifacts from being put in the war:
http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html#packagingExcludes
Also,
http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html#warSourceExcludes
...I can't remember exactly the difference between the two excludes, and it doesn't really matter if you're not overriding the war plugin anyway.
If the javax.mail dependency is a dependency of one of your module, it should be included. However, if it is defined as an optional dependency, it will break the transitive dependency mechanism.
In others words, if in your module, you have that definition:
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.1</version>
<optional>true</optional>
</dependency>
If this is the case, simply remove this <optional>true</optional> statement.

Maven reuse in poms

In our Maven project, we are trying the following directory structure (with about 80 projects total, only a few are shown so that you get the idea):
myappli (pom)
-- module1 (pom)
--|-- utils (pom)
--|-- ejb (pom)
--|--|-- myappli-module1-a-ejb (jar)
--|--|-- myappli-module1-b-ejb (jar)
--|-- war (pom)
--|-- applet (pom)
...
-- module6 (pom)
--|-- utils (pom)
--|-- ejb (pom)
--|--|-- myappli-module6-c-ejb (jar)
--|-- war (pom)
--|-- applet (pom)
Note: This is a flat structure for Maven, as all non-leaf projects have a packaging value of "pom". (cf BetterBuildsWithMaven book).
We define the dependency versions in "dependencyManagement", in the "myappli" pom. This works fine.
Our problem is with the reuse of the dependencies themselves.
For example, the ejb dependencies are common to all ejb projects (by design).
We don't want to cut'n-paste, and maintain all that with each change!
We were thinking to use some "import notion" for the ejb dependencies, and define our ejb dependencies once at the application level. Our unsuccessful attempts were:
The Maven "parent pom" notion would be fine, but it is already used by the modules, so it is not available for our requirement.
No import facility found in Maven (except for dependencyManagement)
XML entity definition is not recognized. We tried a pom like the following, and got the error
"Reason: Parse error reading POM. Reason: could not resolve entity named 'ejbDependencies'":
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project [
<!ENTITY ejbDependencies SYSTEM "./ejbDependencies.txt">
]>
<project ...
...
&ejbDependencies;
...
Edited : I am trying the solution suggested by Robert, but something is wrong.
When I compile my ejb project, it doesn't find the dependencies themselves. I get an error when compiling (mvn compile), saying the javax.ejb package is missing.
Note: I did run "mvn install" on the dependencies project before.
This is my configuration :
<project ...>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.company</groupId>
<artifactId>myproj-maven</artifactId>
<version>3.1-SNAPSHOT</version>
</parent>
<groupId>com.company</groupId>
<artifactId>myproj-maven-ejb</artifactId>
<version>${myproj-version}</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>javax.ejb</groupId>
<artifactId>ejb</artifactId>
</dependency>
<dependency>
<groupId>ojdbc</groupId>
<artifactId>ojdbc</artifactId>
</dependency>
</dependencies>
</project>
---------------------------------
<project ...>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.company</groupId>
<artifactId>myproj-identite-ejb</artifactId>
<version>3.1-SNAPSHOT</version>
</parent>
<groupId>com.company</groupId>
<artifactId>myproj-identite-metier</artifactId>
<name>SNR IDENTITE METIER</name>
<version>2.0.1</version>
<packaging>ejb</packaging>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>myproj-maven-ejb</artifactId>
<version>${myproj-version}</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
I don't know if it changes something, but we have a hierarchy that relates the two poms.
We have a strict Maven structure, where each directory declares all subdirectories as maven modules, and each subdirectory declares the parent as a maven parent.
And the common parent directory is part of this structure.
+---maven
| \---ejb
+---identite
| +---ejb
| | \---SNR_IDENTITE_METIER
Edited:
The answer given by reef seem correct. It is impossible to do with Maven, because our dependency are provided, and therefore not transitive :-(
We really have many problems with setup up Maven. So many little things just don't work. Today I found out that the site target cannot handle properties, that we are using for version numbers!
You can use pom dependencies to import dependencies into arbitrary projects.
A pom project can look similar to:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>persistence-deps</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernateVersion}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${hibernateAnnotationsVersion}</version>
</dependency>
</dependencies>
</project>
And is imported as:
<dependency>
<groupId>com.example</groupId>
<artifactId>persistence-deps</artifactId>
<version>1.0</version>
<type>pom</type>
</dependency>
See Maven, the definitive guide - Grouping Dependencies for details.
Do your imported dependencies have a provided scope?
Indeed this scope is not transitive (see Maven Dependency Scopes).
This could be the reason of the non-replacement.

How to make maven place all jars common to wars inside the same EAR to EAR root?

We have a solution with numerous wars. Wars are similar in the sense they all use hibernate and spring. This means that we have a number of same jars inside each war. This is becoming a problem, because the size of the ear is starting to grow out of proportion.
I would like to use Maven to calculate dependencies and to place all jars common to multiple wars to the root of the EAR.
I tried organizing my project using j2ee archetype (maven-archetype-j2ee-simple), but all wars are still packaged with dependencies inside the WEB-INF/lib.
Is there a way to make Maven calculate common dependencies and place them to EAR, just as he is able to calculate all transitional dependencies when constructing a war or a jar?
As you've mentioned in a comment, it's maven's task to calculate every dependency. When you're creating an artifact, with every common dependency, then you'll also have to guess, which dependencies belong there.
It could also be possible, that you have to deploy one war, with it's dependencies on another machine without an ear, an when you set every war dependency to provided, then you're stuck again.
The only right way, to get skinny wars is from the examples:
http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html
But, and now comes the interesting part, there is one big! shortcut (which completly takes away the mentioned pain), to tell maven, which dependencies your WARs have.
Go inside your EAR-Module an declare a second dependency on the WAR with type pom for every WAR dependency.
<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>
<parent>
<groupId>com.foo</groupId>
<artifactId>skinny</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ear</artifactId>
<packaging>ear</packaging>
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>war</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>war</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>pom</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.8</version>
<configuration>
<skinnyWars>true</skinnyWars>
<defaultLibBundleDir>lib</defaultLibBundleDir>
<modules>
<webModule>
<groupId>com.foo</groupId>
<artifactId>war</artifactId>
</webModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
Now, every WAR will be packaged independently with it's own dependencies and the EAR will be packaged with skinny WARs and every dependency inside the lib folder
Update:
Keep in mind, that the ear/lib folder can't be used for every dependency jar in a strict Container like JBoss EAP 6. JSF Component libraries like tomahawk, primefaces, etc. have to reside in WEB-INF/lib folder.
A handy way to achieve this with the above described solution is to make an exclusion for the component library in the EARs pom.xml like this:
...
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>war</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.foo</groupId>
<artifactId>war</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>pom</type>
<exclusions>
<exclusion>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<exclusion>
</exclusions>
</dependency>
</dependencies>
...
Now every dependency of the WAR will be placed in ear/lib except the component library which will be placed in WEB-INF/lib inside the WAR
Create a new artifact named commons-jars and package it as pom. It should depend on all the common jars you are using - Spring, Hibernate, Log4j, etc.
Then, in each on your wars add it as dependency with scope "provided" (and don't forget to set the type as pom). You will be able to see it in your classpath but they won't be packaged into the war. This way you can also have war specific dependencies packaged into it, which the solution from skinny wars does not provide.
You can set the dependancies scope to "provided". This means they will be provided by some other module and will not be included in the final jar or war.
Perhaps the assembly plugin can help you when packaging up the final EAR and place common jars there.
http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html