IntelliJ - Why Don't Dependencies Import with Maven Module? - maven

I have an IntelliJ project 'myapp' that includes via pom.xml a module called 'common'. The common module is designed to be a place where utility classes and common dependencies are specified like logging.
Here is pom.xml for my app:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>myapp</artifactId>
<packaging>pom</packaging>
<modules>
<module>../common</module>
</modules>
</project>
Here is the pom.xml for the common module:
<project>
… other stuff
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
So I would expect to be able to use commons logging in myapp code without further steps. However, this does not work. Even if I manually add (and export) the common module as a dependency in myapp and mark the commons logging and log4j dependencies as exported in common, it still doesn't work.
Obviously, I can add the logging dependencies directly in myapp pom.xml, but I was hoping for a modular way to do this. I am using IntelliJ 14.1.3 Ultimate.
Any help will be greatly appreciated.
BTW: I tried to include some screen shots in this post, but apparently I don't have at least a '10 reputation' ;)

Related

how to deploy a maven dependency to WildFly

I'm trying to understand how to tell WildFly through maven, that certain libraries are needed.
I have a maven project in eclipse-jee. When I call a JSP, which's backing class works alone, everything is ok. But when I call a JSP, which's backing class uses a class from a library, I get a ClassNotFoundException. When I run that backing class locally instead of on the server, it works perfectly.
The library is added as maven dependency, which is fine as long as I stay local. But when I deploy the WAR to WildFly, the library isn't deployed.
Here's my POM:
<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>
<name>hello_neo4j</name>
<artifactId>myNeo4j</artifactId>
<dependencies>
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0.SP1</version>
</dependency>
<dependency>
<groupId>org.reactivestreams</groupId>
<artifactId>reactive-streams</artifactId>
<version>1.0.3</version>
</dependency>
</dependencies>
<groupId>com.my-domain</groupId>
<version>0.0.1</version>
<packaging>war</packaging>
</project>
As soon as I try to instantiate org.neo4j.driver.Config, I get:
...
Caused by: java.lang.ClassNotFoundException: org.neo4j.driver.Config from [Module "deployment.hello_neo4j.war" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:255)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116)
... 59 more
So, how can I tell eclipse, that it should either package the library in the WAR or deploy it along with the WAR?
I guess, somewhere in the POM should be anything telling that the dependency is to be deployed, but I don't know how.
In the effective POM, I see <scope>compile</scope> and I thought, it would mean that the dependency would be compiled into the POM. But obviously, I need something more, but what?
Thanks in advance for your helpful comments!
before posting the question, I had searched really long... But now, short after posting it, I found the answer: Just another dependency is needed in order to enable the server to resolve the dependencies from the deployed POM:
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-M1</version>
<type>maven-plugin</type>
<scope>runtime</scope>
</dependency>
Hope, this might help others to search a shorter time than I did.

Spring Boot project in IntelliJ IDEA stops working after reboot

This is probably a newbie question, but I am not able to sort things out.
I've created a Spring Boot JAR-based Maven project using the Spring Initializr interface in IntelliJ IDEA. Its dependencies on Web and JDBC; an embedded instance of Tomcat is used to run the project.
I also have a couple of other Maven dependencies I add without problems from the relevant dialog; I also manually add the Apache Phoenix thin client JAR, that includes a copy of Logback (I am not able to get their Maven repository to work, but I don't think this is relevant to this question).
I am able to run the project flawlessly; after a system reboot (I am on Windows), a cascade of errors follows. First and foremost an exception signaling a conflict between Logback comes:
Exception in thread "main" java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from [...]). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml: org.slf4j.impl.Log4jLoggerFactory.
I would not like to alter the Phoenix client JAR; I am able to follow the instructions to replace the Spring dependency on Logback with another logger (log4j2 for example), but then the embedded Tomcat fails to create the container.
To get back to work, I have to recreate the project from scratch.
Could you please point me in the right direction to pinpoint the actual problem? Thank you.
Post scriptum: I am attaching the content of my pom.xml, apart from some potentially identifying information.
<?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>[RETRACTED]</groupId>
<artifactId>[RETRACTED]</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>[RETRACTED]</name>
<description>[RETRACTED]</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.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>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Firstly, rather than adding the apache phoenix client (or any other dependencies) manually you should add them to your maven pom.xml, so maven resolves the dependency at build time. If your project has dependencies which maven is failing to resolve this is a separate issue which you need to resolve, but adding them manually is bad practice for a number of reasons.
Once you have added the phoenix client as a dependency, you need to explicitly exclude slf4j-log4j12 and log4j as part of the dependency declaration. The XML should look something like this:
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>4.13.1-HBase-1.3</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
The reason these need excluded is that they are conflicting with the versions bundled in the spring-boot project
Hopefully this will sort your problem.

Maven issue when overriding an environment specific systemPath property

I experienced issues with a maven build that does not behave the same way if done on Windows (like they were done in the past) or Linux (like I want to do them now).
I want to build a project that has a dependency on another project that pom that itself imports a pom that contains a Windows path.
my project | other project
|
mybuild -------|------> pom --------> pom with systemPath
dependency import
|
But in a nutshell, here is my pom:
<groupId>test.properties</groupId>
<artifactId>buildme</artifactId>
<version>1.0-SNAPSHOT</version>
...
<dependencies>
<dependency>
<groupId>test.properties.installme</groupId>
<artifactId>module</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
</dependency>
</dependencies>
And I depend on a pom that looks like this (not under my control)
<groupId>test.properties.installme</groupId>
<artifactId>module</artifactId>
<version>1.0-SNAPSHOT</version>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>test.properties.installme</groupId>
<artifactId>dependency</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
and the problem lies in this last pom (not under my control):
<modelVersion>4.0.0</modelVersion>
<groupId>test.properties.installme</groupId>
<artifactId>dependency</artifactId>
<version>1.0-SNAPSHOT</version>
...
<properties>
<com.sun.tools.path>D:/java/jdk1.8.0_65/lib/tools.jar</com.sun.tools.path>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${com.sun.tools.path}</systemPath>
</dependency>
</dependencies>
</dependencyManagement>
I have no control on the other project in question. I totally agree that a refactoring to use environment variable in place of the hard coded paths would solve my problem.
But instead the Windows path is defined in a property. One would think that overriding the value of the property depending on my platform would be enough. But it is not.
Unfortunately in this precise case case maven seems to behave to behave poorly.
Before applying any property override in any form (in settings.xml, -Dproperty=, redefinition in root pom), maven starts building the effective pom. And during that step, if it finds the pattern I mentioned above (a dependency on another pom that itself imports a pom that contains a Windows path), then it says:
The POM for <groupId>:<artifactId>:jar:<version> is invalid, transitive dependencies (if any) will not be available
As a consequence, my project needs to explicitly define all the dependencies of the second project. And I cannot rely on transitive dependencies which gives me a lot of trouble.
In order to illustrate the issue, I created a minimal example showing the problem. It can be found here:
https://github.com/fabricepipart/test-properties
Do you see any workaround for this?
Any way to override the value of the property and still benefit from the maven transitive dependencies?
Thanks a lot

Maven: Package "brother" projects

I am working on a big set of projects strongly related to each other and looking for a way to reduce to minimimun the maintenance overhead using a good maven configuration.
One of the scenarios which I am currently working on is a set of several small projects inside the same "company project", most of them depending on the others, with a big list of external dependencies in each one.
In order to make it cleaner I created a parent pom, set all of them as modules and created a big list of dependencies inside the parent's dependencyManagement section allowing me to remove most of the version tags inside the project poms.
The next stage for me is to reduce the amount of resulting jars by making use of some plugin, such as one-jar or assembly, in oder to get a signle jar from one of those projects containing all the others inside. However, this led me to having an enourmous jar with tons of external libraries inside, most of them already provided by the running environment.
I know that adding the <scope>provided</scope> tag to the declaration of external dependencies would do the job, but I would like to avoid having dozens of these tags in my poms.
So the questions are:
Is there any way to define a default scope, so I can use compile scope only in the libs which I want included?
Then, instead of having this:
<dependencyManagement>
<dependency>
<groupId>any.external</groupId>
<artifactId>lib</artifactId>
<version>1.0</version>
<scope>provided</scope> <!--Skip Inclusion-->
</dependency>
<dependency>
<groupId>any.external</groupId>
<artifactId>cool-lib</artifactId>
<version>1.0</version>
<scope>provided</scope> <!--Skip Inclusion-->
</dependency>
<dependency>
<groupId>another.external</groupId>
<artifactId>lib</artifactId>
<version>1.0</version>
<scope>provided</scope> <!--Skip Inclusion-->
</dependency>
<dependency>
<groupId>my.company</groupId>
<artifactId>some-dependency</artifactId>
<version>1.0</version>
</dependency>
</dependencyManagement>
I could have this (note that the difference will come when we have only 10 internal projects to include, but more than 100 external libs):
<dependencyManagement>
<dependency>
<groupId>any.external</groupId>
<artifactId>lib</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>any.external</groupId>
<artifactId>cool-lib</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>another.external</groupId>
<artifactId>lib</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>my.company</groupId>
<artifactId>some-dependency</artifactId>
<version>1.0</version>
<scope>compile</scope><!-- Include It! -->
</dependency>
</dependencyManagement>
Or better: Maybe I'm skipping something and there is already a way to tell maven: "Include only the jars generated within the current project"?
Remember that all modules are "brothers", included as modules of the same parent, and compiled at the same time.
Many thanks in advance!
Carles

Multi-module maven build : different result from parent and from module

I am migrating an application from ant build to maven 3 build.
This app is composed by :
A parent project specifying all the modules to build
A project generating classes with jaxb and building a jar with them
A project building an ejb project
3 projects building war modules
1 project building an ear
Here is an extract from my parent pom :
<groupId>com.test</groupId>
<artifactId>P</artifactId>
<packaging>pom</packaging>
<version>04.01.00</version>
<modules>
<module>../PValidationJaxb</module> <-- jar
<module>../PValidation</module> <-- ejb
<module>../PImport</module> <-- war
<module>../PTerminal</module> <-- war
<module>../PWebService</module> <-- war
<module>../PEAR</module> <-- ear
</modules>
I have several problems which I think have the same origin, probably a dependency management issue that I cannot figure out :
The generated modules are different depending on if I build from the parent pom or a single module. Typically if I build PImport only, the generated war is similar to what I had with my ant build and if I build from the parent pom, my war took 20MB, a lot of dependencies from other modules had been added. Both wars are running well.
My project PWebService has unit tests to be executed during the build. It is using mock-ejb which has cglib as dependency. Having a problem of ClassNotFound with this one, I had to exclude it and add a dependency to cglib-nodep (see last pom extract). If I then build only this module, it is working well. But if I build from the parent project, it fails because other dependencies in other modules also had an implicit dependency on cglib. I had to exclude it in every modules pom and add the dependency to cglib-nodep everywhere to make it run.
Do I miss something important in my configuration ?
The PValidation pom extract :
It is creating a jar containing an ejb with interfaces generated by xdoclet, as well as a client jar.
<parent>
<groupId>com.test</groupId>
<artifactId>P</artifactId>
<version>04.01.00</version>
</parent>
<artifactId>P-validation</artifactId>
<packaging>ejb</packaging>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>P-jaxb</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.5.ga</version>
<exclusions>
<exclusion>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.2.2</version>
</dependency>
...
[other libs]
...
</dependencies>
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<configuration>
<ejbVersion>2.0</ejbVersion>
<generateClient>true</generateClient>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xdoclet-maven-plugin</artifactId>
...
The PImport pom extract :
It depends on both Jaxb generated jar and the ejb client jar.
<parent>
<groupId>com.test</groupId>
<artifactId>P</artifactId>
<version>04.01.00</version>
</parent>
<artifactId>P-import</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>P-jaxb</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.test</groupId>
<artifactId>P-validation</artifactId>
<version>${project.version}</version>
<type>ejb-client</type>
</dependency>
...
[other libs]
...
</dependencies>
The PWebService pom extract :
<parent>
<groupId>com.test</groupId>
<artifactId>P</artifactId>
<version>04.01.00</version>
</parent>
<artifactId>P-webservice</artifactId>
<packaging>war</packaging>
<properties>
<jersey.version>1.14</jersey.version>
</properties>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.rte.etso</groupId>
<artifactId>etso-validation</artifactId>
<version>${project.version}</version>
<type>ejb-client</type>
</dependency>
...
[other libs]
...
<dependency>
<groupId>org.mockejb</groupId>
<artifactId>mockejb</artifactId>
<version>0.6-beta2</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>cglib</groupId>
<artifactId>cglib-full</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.2.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Many thanks
Solution after modification of the configuration :
When I got the projects already mavenized, it didnt respect the folder layout convention, but as it was declared in the pom where to find the sources, I thought it would be working.
Anyway, i changed it to match the recommended structure.
To build a single module I was executing mvn clean install directly at its level. It is this way I obtained a different result (which is in fact the one I wanted).
Anyway, my problem is solved, I put all the dependencies of the PValidation project as provided, as I am only including the generated client in other modules and they dont require all what is needed for the implementation.
But still I dont get why I had different result for the same configuration.
The first important thing is you should create the structure of your project appropriate to the modules structure which means having the following folder structure:
+-- parent
+-- PValidationJaxb
+-- PValidation
+-- PImport
+-- PTerminal
+-- PWebService
+-- PEAR
This means having a pom.xml which contains the modules definition in the parent folder.
if you follow the above recommendation you can simplify the modules list to the following:
<modules>
<module>PValidationJaxb</module> <-- jar
<module>PValidation</module> <-- ejb
<module>PImport</module> <-- war
<module>PTerminal</module> <-- war
<module>PWebService</module> <-- war
<module>PEAR</module> <-- ear
</modules>
Furthermore a best practice in Maven is to use lowercase artifacts which mean in your case pvalidationjaxb instead of PValidationJaxb.
An other important thing is your version which does NOT follow the Maven conventions. Furthermore your version will be from the Maven point of view a release which is not the case you are doing development on this. In Maven you should use a so called SNAPSHOT for such purposes like 1.0.0-SNAPSHOT.
I hope you have followed the folder layout recommendation of Maven which says to put production code (which will be packaged into the resulting jar) into src/main/java whereas test code into src/test/java.
The problem you described having different dependencies sounds weired. The question is how have you tried to build a single moduel? This can usualy be achieved by using the following from the parent location:
mvn -pl module clean package
The problem with your unit tests sounds like a missing dependencies etc. but here is the questions how have you tried to run the unit tests and have you configured maven-surefire-plugin ? Or do you have integration tests? This is only a guess cause i don't see any configuration of Maven plugins in your poms.

Resources