Log4j2 custom plugins - annotation processing with Maven Assembly Plugin - java

I am not very familiar with Maven, I started using it just yesterday, but I like it. In my project I use Log4j2 library for logging and because of insufficiecy of advanced plugins (like appenders, converters) I need to use custom plugins. log4j-api and log4j-core (also with a bunch of other libraries) are added as dependencies in pom.xml associated with my project. Actually I am using version 2.0 of Log4j.
Log4j uses annotation processing to pre-load classes marked as #Plugin. As far as I know, in older releases of log4j, additional plugin entry had to be specified in pom.xml to trigger plugin processing, or the packages with custom plugins had to be typed into the packages attribute in the configuration file (https://logging.apache.org/log4j/2.x/manual/configuration.html#ConfigurationSyntax). But this is not supported since 2.0-rc2.
In v2.0 this should be done automatically, as long as log4j-core is available to the building engine. There is a file Log4j2Plugins.dat in myproject-0.0.1-SNAPSHOT.jar/META-INF/org/apache/logging/log4j/core/config/plugins/ that contains mappings of my custom plugins - that's OK.
For building with Maven I use also Maven Assembly Plugin. Its goal single is binded to package phase. After packaging the project I naturally have one additional jar in the target directory - myproject-0.0.1-SNAPSHOT-jar-with-dependencies.jar. However, Log4j2Plugins.dat file in this jar contains mappings of original plugins, the same file as in the log4j-core library. And that's the problem, since it doesn't hold any references to my custom plugins. It seems that the file from myproject-0.0.1-SNAPSHOT.jar is being overwritten with the original file from the log4j library, but I am not sure what's the case.
So when I run myproject-0.0.1-SNAPSHOT-jar-with-dependencies.jar, log4j can't find the plugin classes from my project. I think that myproject-0.0.1-SNAPSHOT.jar would run ok, but I can't run it without the dependencies.
The packages attribute in configuration should be re-enabled in 2.0.1 release, but if I don't want to wait for the release, I have to use the annotation processing method.
Do you have an idea how to fix it?
I tried to run it with release 2.0-rc1 of log4j, where the packages attribute of the configuration element was usable. The result is: log4j successfully loaded the class of my custom plugin. However, there were so many other errors (that arised in this specific release) that make the program even more unusable.
This is one good point, that ensures me that if the packages attribute will be enabled in next release 2.0.1, my plugin will work. It should be reinstated according to this issue tracking: https://issues.apache.org/jira/browse/LOG4J2-741
Added my pom.xml
<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.jjurm</groupId>
<artifactId>twbot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>twbot</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.jjurm.twbot.system.Run</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.jjurm.twbot.system.Run</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>1.1.7</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>net.snaq</groupId>
<artifactId>dbpool</artifactId>
<version>6.0</version>
</dependency>
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<version>1.11</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>commons-jxpath</groupId>
<artifactId>commons-jxpath</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.15</version>
</dependency>
</dependencies>
</project>

I think the problem stems from packaging the dependencies into the jar. Doing a quick dive into the code, it looks like the plugin processor overwrites the plugin dat file for each set of plugins it handles. My guess is that during the packaging process, your custom plugins are processed and written to the dat file, and then overwritten when your log4j dependency is processed for inclusion in the package. There may be better solutions, but off the top of my head I would suggest that you do one of the following:
Do not package the dependencies into your jar. Just package your project and then include the dependencies on your classpath when you execute. Even if you want to package everything in a single portable jar, doing this would allow you to at least confirm if your plugins are being overwritten, or if there is something else wrong.
Create a separate project for your custom plugins, package it separately from your main project, and then include the resulting jar as a dependency. As with option 1, make sure that you do not include the log4j jars in this package. Once you have created your custom plugin jar, you can package it along with the other dependencies in your main jar and it should work fine since your custom plugin jar will have its own plugin dat file.
Good luck!

Another solution is mentioned in Log4j 2 issue 673. Use maven shade plugin with specific transformer instead of maven assembly plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<transformers>
<transformer implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer" />
</transformers>
</configuration>
<dependencies>
<dependency>
<groupId>com.github.edwgiz</groupId>
<artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
<version>2.6.1</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
If I understand it accurately, transformer creates Log4j2Plugins.dat file by correctly merging Log4j2Plugins.dat from all dependencies and the main jar, i.e. all plugins will be included.

Related

Error: JavaFX runtime components are missing, and are required to run this application Using Intelij on Linux

I've recently decided to take the plunge and start programming on Linux but the transition has been rough.
I'm currently trying to get a JavaFX program to run properly in InteliJ and I keep getting an error for Error: JavaFX runtime components are missing, and are required to run this application
I've tried several of the proposed fixes that you can find on Stack Overflow, namely this one and this one along with the walk-through on Gluon's own website but nothing that I have tried so far is working.
For a brief overview, I'm using...
Java 17 (I don't remember why exactly anymore).
JavaFX 19 through Maven
InteliJ Idea Community
& Fedora Workstation
I know for a fact that the code itself is good because it is the exact same code that I used on my windows machine and it worked fine. The only thing I've changed in regards to the code is the pom.xml file for Maven where I finally added JavaFX as a dependency while getting things ready for the new OS.
This is the pom.xml file. I'm not an expert with maven but everything does appear to be correct as best I can tell.
<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>LibraryDesktopApp</groupId>
<artifactId>LibraryDesktopApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>LibraryDesktopAppProgram</name>
<description>This is the desktop program for the library software suite.</description>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>19</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>19</version>
</dependency>
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>11.1.1</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.mypackage.MyClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>LibraryDesktop/src.Main</mainClass>
<launcher>app</launcher>
<jlinkZipName>app</jlinkZipName>
<jlinkImageName>app</jlinkImageName>
<noManPages>true</noManPages>
<stripDebug>true</stripDebug>
<noHeaderFiles>true</noHeaderFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
These are screenshots of various configuration screens.
Libraries
Modules
Configuration
I have tried running the program both with and without the VM arguments and neither worked.
Any help would be greatly appreciated! Thanks!
The entire project was converted over to a modular approach and I re-worked the pom.xml file too.
It was a bit of headache to get working but in addition to fixing my issue, the new setup is honestly much nicer than what I was dealing with before.
On the off chance that someone else needs help with this same issue, I'm attaching a link to a fairly straightforward setup very similar to what I'm using. It does the job of explaining the process far better than I could.

unable to find logger class while running a maven build jar file

I am trying to write a maven integrated Java API. I have included log4j for logging purpose. Which works well when running through eclipse, but when maven package is done and the jar is run it is unable to run from cmd line using java -jar jar_name.jar throwing an error
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
Now the log4j.properties file is placed under src/main/resources folder. And the pom.xml is mentioned. Have tried searching for answers but none worked for me.
Any help available
<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>Weather_Simulator</groupId>
<artifactId>weather_simulator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>weather_simulator</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.test.weather.simulator.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<!-- NOTE: We don't need a groupId specification because the group is
org.apache.maven.plugins ...which is assumed by default.
-->
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-configuration2</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
Your <scope> in your pom.xml appears to be wrong. Try this (notice I've changed "test" to "compile").
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.6.1</version>
<scope>compile</scope> <!-- look here -->
</dependency>
The way you currently have your pom.xml configured (with "test"), maven will only provide the log4j jar when doing "mvn test". If you need the jar at both compile time and run time (which is the scenario that appears to be causing problems for you), the scope needs to be "compile".
Note that "compile" is the default scope, so if you leave the <scope> element off, the scope will be "compile".
From the maven docs: "This [compile] is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects"
For more info about maven "scopes" look here.
This is a classpath problem, the jar generated by Maven contains only your classes. To fix this you can pack all the dependencies inside your project jar: How can I create an executable JAR with dependencies using Maven?
There are two things you should be aware if you like to create an executable jar which contains all dependent jars you have to use maven-assembly-plugin as you already did but you forgot to bind it to the life cycle...which looks like this:
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
[...]
</project>
Furthermore having plugins as dependencies is simply wrong..
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
</dependency>
This means remove this entry from your pom file.
Defining a dependency with a scope test means it will be available only during the unit tests which means also it will never being packaged into a resulting jar file. This means you have to change the following:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.6.1</version>
<scope>test</scope>
</dependency>
into the following:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.6.1</version>
</dependency>
After you have fixed those issues you should be able to build your app via:
mvn clean package
and find the resulting jar file which contains the dependencies in the target directory named like weather_simulator-1.0.0-SNAPSHOT-jar-with-dependencies.jar which you should use to call your app.

Not adding JARs to staging folder on Google Cloud when using Maven

I'm running integration tests on the cloud for the Google Cloud Dataflows that I have written; checking that they read from Pub/Sub and write to BigQuery correctly, but when using Maven (mvn clean install), the staging folder is not populated with the required JARs. The only JAR that appears is a surefirebooter.jar. As a result, I get a NoClassDefFoundError for PipelineOptions (most likely because it is the first class from a dependency that's trying to be referenced) in the Stackdriver logs, and consequently the tests fail. Since they're running on the cloud I am indeed using a DataflowRunner as opposed to a DirectRunner.
When I run the integration tests from my IDE they work fine; the staging folder is populated with all the JARs and all is well. Also, when I run the tests using Maven but with a DirectRunner the tests run successfully, thus my problem only occurs when using Maven and a DataflowRunner. I assume that problem therefore lies with the pom.xml file, which I have given below:
<?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>group</groupId>
<artifactId>artifact</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.cloud.dataflow</groupId>
<artifactId>google-cloud-dataflow-java-sdk-all</artifactId>
<version>2.0.0-beta3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.0.0-M3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Anyone know why this is happening and how I may resolve it?
When staging files, the Dataflow runner will automatically stage the the classes available to the current class loader. I believe that surefire plays some tricks with the classloader to make the tests easier to run.
One option would be to specify filesToStage on the pipeline options, which will override the normal "detect JARs to stage from the class loader". Alternatively, look at how surefire is managing the classpath, and make sure the SDK JARs are available in the classloader the test is running in.

How to use a custom library in Maven?

I am working on a software that uses Maven. My friend who works with me on it recently added a IO-Lib which makes it easier to handle packets sent by Minecaft: Pocket Edition Click here to see the software I'm talking about But, since the jar is not on the Maven Repo, I can use dependency the normal way. Is there anyway to use a custom library not in the maven repo?
My pom.xml:
<project>
<?xml version="1.0" encoding="UTF-8"?>
<groupId>net.trenterprises.diamondcore</groupId>
<artifactId>DiamondCore</artifactId>
<version>0.1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.0-rc1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.0-rc1</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>net.trenterprises.diamondcore.run</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<organization>
<name>Trenterprises</name>
</organization>
</project>
If the custom jar file is not in maven central, the next best thing is for it to be in a different repo. If that's the case, you can add additional repository details to the pom.xml file and it will pull from both repos.
The second best thing is to use the "mvn install:install-file" target to manually install the binary into your cache. Then it will resolve in environments backed by your cache. If you have a build system that lives outside of your working environment, it gets just a little bit harder.
Assuming you have to make this work in multiple maven environments (not just your own) and you don't have a private repository, you need to create one. You can download various maven repository management systems (Artifactory, etc.) install them, and then configure your in-house repository the same way you would add a second out-of-house repository.
If setting up a repository server seems daunting to you, while it is far from a perfect solution, for a little while you can use the "mvn install:install-file" target to install the file in each local cache (but one typo or cache clear and it's going to be messed up in that cache)
You may want to add a system scoped dependency. have a look here:
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope
it explains the various ways you can import a dependency. not all require the dependency be held in a repository.
I think this is what lhasadad was talking about, but to elaborate: I have used <scope>system</scope> and <systemPath>some/path/to.jar</systemPath> to point Maven at local jars successfully in the past. For example:
<dependency>
<groupId>org.apache</groupId>
<artifactId>kafka_2.8.2</artifactId>
<version>${kafka.version}</version>
<type>jar</type>
<scope>system</scope>
<systemPath>${basedir}/lib/kafka_2.8.2-${kafka.version}.jar</systemPath>
</dependency>

Duplicate classes when using Maven AspectJ weave dependencies

We are using the Maven AspectJ plugin to build our web application. It makes use of "weaveDependencies" to add aspects to some dependency jar files.
Now we end up with two versions of some classes in the web application archive, one in WEB-INF/classes and one in the original jar file in WEB-INF/lib. It seems that only the one in classes has the aspects.
I am afraid that this can cause problems.
What is the best way to fix this?
The same problem is discussed (without solution) over at the Eclipse forums.
The whole pom.xml itself is huge, and of course the sub-projects that are included have their own, too. I hope the extract below from the WAR project is informative enough.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
<filters>
<filter>${basedir}/src/etc/${environment}/environment.properties</filter>
</filters>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.2</version> <!-- NB: do use 1.3 or 1.3.x due to MASPECTJ-90 - wait for 1.4 -->
<dependencies>
<!-- NB: You must use Maven 2.0.9 or above or these are ignored (see
MNG-2972) -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<outxml>true</outxml>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
<weaveDependencies>
<weaveDependency>
<groupId>OURPROJECT</groupId>
<artifactId>OURPROJECT-api</artifactId>
</weaveDependency>
<weaveDependency>
<groupId>OURPROJECT</groupId>
<artifactId>OURPROJECT-service</artifactId>
</weaveDependency>
</weaveDependencies>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
In a servlet container and inside a WAR, the classes inside WEB-INF/classes always have precedence over classes with the exact same name found inside a jar in WEB-INF/lib.
This is a quote from the servlet spec:
The Web application class loader must load classes from the WEB-INF/
classes directory first, and then from library JARs in the
WEB-INF/lib directory.
This has been so since at least Servlet 2.4. This allows an application to selectively patch just a few library classes without having to repackage jars manually or via maven plugins.
In your case you can be certain that the classes with the aspects will always be taken, as they are in WEB-INF/classes and have priority over classes in WEB-INF/lib.

Categories

Resources