appplication failed when try to use one module classes in another module? - java

I have any modules in my spring-application on maven
First module build and I have war
Another Second module needs to import classes from a first.
Using this article this
I added this in first pom.xml
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<attachClasses>true</attachClasses>
<classesClassifier>classes</classesClassifier>
</configuration>
</plugin>
And after builing there is jar file in directory
Than I added dependency in second module
<dependency>
<groupId>ru.myProject</groupId>
<artifactId>MyProject-webapp</artifactId>
<version>${project.version}</version>
<classifier>classes</classifier>
</dependency>
and build all together
So, there are jar files in ear archive in lib folder, but when try to start - there is error message without logs.
Can you help me to fix it or get idea?
May be the root cause in that, second application already contained own spring-application context and initialization?

Related

Maven org.springframework.beans.factory.BeanCreationException Caused by: java.lang.NoClassDefFoundError [duplicate]

I have an external .jar that cannot be imported from public repositories using pom.xml, it's sqljdbc41.jar.
I can run the project locally from my IDE, and everything will work. I referenced the library after downloading it like so:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc41</artifactId>
<version>4.1</version>
<scope>system</scope>
<systemPath>${basedir}/lib/sqljdbc41.jar</systemPath>
</dependency>
When I run mvn clean package to create my .jar file and try to run the created .jar, a mistake will pop up, which mentions the SQL Server references are not valid. I then extracted my .jar file and true enough, everything that is referenced in the pom.xml file properly gets downloaded and added, however, my SQL Server does not.
I can, in a very hacky way* just manually add the sqljdbc41.jar to my /lib folder after it's been compiled as a .jar, and it'll work, however that seems highly unoptimal. What would be a better approach?
*Opening the .jar file with Winrar, going to the /lib folder, manually selecting my sqljdbc41.jar file, then make sure to select the No Compression option bottom left where Winrar gives you compression options, in case you find this by Google and no one answered.
you can set 'includeSystemScope' to true.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
You could install the sqljdbc41.jar in your local repository :
mvn install:install-file -Dfile=path/to/sqljdbc41.jar -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc41 -Dversion=4.1 -Dpackaging=jar
And then declare the dependency as a standard dependency :
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc41</artifactId>
<version>4.1</version>
</dependency>
If you use a remote artifact repository (nexus, archiva...) you also need to deploy the artifact on this repository. You can find more here : https://maven.apache.org/guides/mini/guide-3rd-party-jars-remote.html
Another way, you can put it into the resources folder, such as resources/lib/xxx.jar, then config the pom.xml like this:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc41</artifactId>
<version>4.1</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/resources/lib/sqljdbc41.jar</systemPath>
</dependency>
In Spring Boot: I also faced similar issue and below code helped me.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.7.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
It works for me:
project {root folder}/libs/ojdbc-11.2.0.3.jar
pom.xml:
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>11.2.0.3</version>
<scope>system</scope>
<systemPath>${basedir}/libs/ojdbc-11.2.0.3.jar</systemPath>
</dependency>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
In my case, the fault was providing a version number without "dot" in tag:
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<scope>system</scope>
<version>1</version>
<systemPath>${basedir}/src/main/resources/lib/tools.jar</systemPath>
</dependency>
This one works:
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<scope>system</scope>
<version>1.8</version>
<systemPath>${basedir}/src/main/resources/lib/tools.jar</systemPath>
</dependency>
When Spring-Boot projects are used with maven or gradle plugins they packaged the applicaiton by default as executable jars.
These executable jars cannot be used as dependency in any another Spring-Boot project because the executable jar add classes in BOOT-INF/classes folder. This means that they cannot be found when the executable jar is used as a dependency because the dependency jar will also have the same class path structure as shown below.
If we want to use project-A as a maven dependency in project-B then we must have two artifacts. To produce the two artifacts, one that can be used as a dependency and one that is executable, a classifier must be specified. This classifier is applied to the name of the executable archive, leaving the default archive for use as a dependency.
To configure a classifier of exec in Maven, you can use the following configuration:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
</build>
So the MAJIC WORD here is <classifier>exec</classifier> this will create a jar structure as below and then it could easily be conusmed by spring-boot project as maven dependency jar on class path.
The above plugin need to be add in project-A pom that is going to be used as dependency in project-B. Same is explained in spring documentation section 16.5. as well.
In order to work through the local repository, the target .jar file that we will work with must be in the s2 folder. Several methods can be used for this:
The file can be taken manually and put in the relevant place (not
preferred). The same process can be done by installing it via the
console.
Relevant Remote URL is written in the .pom file dependencies and
automatically places it in the s2 folder when Intellij is refreshed
(validate) in the IDE used.
The same process can be done by addressing the .pom file dependencies via the centeral repository.
Attention: ComponentScan should not be forgotten for the related jar work on SpringBot.

Maven: download source from github, compile into jar, include jar in WEB-INF/lib directory

There are many "solutions" to this issue which I have tried to no avail, so please forgive me if this seems redundant.
I have a Java/Maven project being built with Intellij IDEA which has a dependency on the jar file built from this GitHub project: https://github.com/protegeproject/snap-sparql-query
Unfortunately, the jar is NOT in any external repository so must be built by me. I have the build working and manually copy the jar into the WEB-INF/lib folder of my parent project. Intellij then runs correctly, all dependent jars are found at execution even though the resulting war file does not contain the snap-sparql-query jar. I'm guessing it is getting cached somewhere.
If I build the project from the command line ($ mvn clean package) it builds but the above jar file still is NOT included in the resulting war file, even if it exists in the WEB-INF/lib folder of the parent before being packaged as a war file.
The ideal solution would be Maven commands in the parent that:
download the source for snap-sparql-query
compile the source into a jar
copy the jar to the parent WEB-INF/lib directory
all jars in the WEB-INF/lib directory get included in the war file
At the very least I'd be satisfied manually performing items 1-3 above, but have Maven perform #4.
Here is the Maven entry for snap-sparql-query:
<!-- SNAP SPARQL API -->
<!-- https://github.com/protegeproject/snap-sparql-query -->
<dependency>
<groupId>edu.stanford.protege</groupId>
<artifactId>snap-sparql-query-api</artifactId>
<version>4.0.0-SNAPSHOT</version>
<!-- this library isn't found in the maven repository, must be externally compiled -->
<!-- and copied to the ...WEB-INF/lib directory so this pom can find it -->
<scope>system</scope>
<systemPath>${basedir}/WEB-INF/lib/snap-sparql-query-api-4.0.0-SNAPSHOT.jar</systemPath>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>edu.stanford.protege</groupId>
<artifactId>de-derivo-sparqldlapi</artifactId>
<version>2.0.0</version>
<!--<version>3.0.0</version>-->
</dependency>
I've been warned using the systemPath is bad, so I would like to avoid that too, if possible.
Can I have Maven perform at least item 4 above, and/or ideally 1-4?
You asked multiple things and in order to answer all, I need more
details. I will update the answer once you provide those details. But for now, below is the answer for the Item 4 in your list.
By default Maven will not include System scoped jars in the packaged application. In order to include System scoped dependencies you need to use maven-dependency-plugin's copy- dependency goal.
Please note the <phase>prepare-package</phase>. Having phase prepare-package is very important to include the dependencies in the WAR file since this goal needs to be executed before the execution of maven-war-plugin.
<build>
<finalName>maven-sys-scope</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dep</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>system</includeScope>
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

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>

Maven web project, Class not found Exception in war for external jars

I have a maven web project for which i was required to include some third party jars (not present online) so i installed them using
<dependency>
<groupId>com.smas.cluster</groupId>
<artifactId>cluster-smas</artifactId>
<version>2.0-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/cluster-smas-2.0-SNAPSHOT.jar</systemPath>
</dependency>
The Problem which i am facing is when i run maven clean install the war file generated didnot included the 3rd party jar.
After searching i found a solution i copied jar in lib folder (created at root directory of project) and Then i used following snippet in Pom file
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<webResources>
<resource>
<directory>${project.basedir}/libs/</directory>
<targetPath>WEB-INF/lib</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
The jar are now copied from my lib folder to WEB-INF/lib/ in generated war file. But when i run the service i get error of Class not found exception.
Try this, remove system scope and systemPath, and remove the war plugin, leaving just the dependency declaration.
<dependency>
<groupId>com.smas.cluster</groupId>
<artifactId>cluster-smas</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
Build your project. Your dependency JAR should appear in WEB-INF/lib and the classes will be available at runtime.

not importing class from name-sources.jar

I have created a maven war project, and want to call it from another module (war). When I searched found that name-sources.jar file is used as dependency to another module. I am adding dependency of name-sources but import is not working.
name-SNAPSHOT.war
name-SNAPSHOT-sources.jar
are the files generated on building of maven project.
Below is the dependency added into another module.
<dependency>
<groupId>uniqueid</groupId>
<artifactId>name</artifactId>
<version>8.9-SNAPSHOT</version>
<classifier>sources</classifier>
<scope>system</scope>
<systemPath>{Path}/name-8.9-SNAPSHOT-sources.jar</systemPath>
</dependency>
Any help is highly appreciated.
I understand this: you have 2 web projects A and B, both with maven packaging = war. In A, there are classes you want to use in B.
Forget about adding a *-sources.jar as dependency.
So, do this:
generate a new maven project C as a library with project packaging "jar"
Move the classes you want to share from A to C
Install this artifact C in your local maven repository (mvn install)
Then, add a dependency to C in the pom.xmls of A and B:
<dependency>
<groupId>your.group</groupId>
<artifactId>yourLibrary</artifactId>
<version>0.1.0-SNAPSHOT</version>
<scope>compile</compile> <!-- this is default, so this line is optional-->
</dependency>
Created *-classes.jar file. Use below code under pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
And added this new jar as dependency wherever want to use.
<dependency>
<groupId>com.honeywell.dras.sensibo</groupId>
<artifactId>sensibo-client</artifactId>
<version>{*}</version>
<classifier>classes</classifier>
</dependency>
So advantage with this is we can generate both war and jar files and make use of both based on need.

Categories

Resources