Maven: xpp3 versus xpp3_min - maven

In my Java Maven project, two of my codes direct dependencies use a sub-dependency of XPP3. However, one of them has the artifact ID xpp3 while the other one has the artifact ID xpp3_min. Both are version 1.1.4c. Does anyone know the difference between the two? My project allows both to be dependencies without marking either of them as excluded due to conflict.
Home page for XPP3 project: http://www.extreme.indiana.edu/xgws/xsoap/xpp/
Maven repository reference: http://mvnrepository.com/artifact/xpp3/xpp3_min and http://mvnrepository.com/artifact/xpp3/xpp3. Notice how both projects have the same description. I don't just want to naively assume that _min is a minimal version due to its name suffix.

I've opened both archives and the xpp3_min only includes the XmlPullParser.class and XmlPullParserException.class (and MXParser.class). It doesn't include other classes like XmlPullParserFactory etc...
A popular obj <-> xml serialzer package: XStream, has both a dependency on XPP3_MIN and XMLPULL, where XMLPULL implements the XmlPullParserFactory. If it had a dependency on XPP3 it sure would have a classloading issue.

Related

Meaning of SCOPE tag in Maven Dependency

When we use scope tag while providing dependencies in POM file of Maven, we can give several valid values (compile, run, provided etc..). I understand that tag is applicable for only transitive dependencies (i.: list of JARs required by direct dependencies that we give in POM).
When we give the scope as provided, will the dependency not be downloaded from Maven central repository ? Can someone please confirm.
Thanks!
Dependencies with scope provided are meant to be provided by the container in which the application runs (e.g. provided by jboss).
This means that they are downloaded by Maven, put on the compile and test classpath, but not included into the final WAR or EAR you are building.

How to write AOP #Around for a package from specific dependency

I have multiple packages with same name like org.abc.com.client.* in different external libraries/dependencies which have same groupId name but unique artifactId name.
Therefore, it looks like:
<dependency>
<groupId>same_name</groupId>
<artifactId>unique</artifactId>
<version>same_or_different</version>
</dependency>
and unique artifactId has same package name. I don't need AOP for a class.
I want write #Around for a package specific to particular artifactId.
#Around("call(* package(org.abc.com.client)_of_specific_artifactId1(..))")
public void doSomething(){}
#Around("call(* package(org.abc.com.client)_of_specific_artifactId2(..))")
public void logSomething(){}
The artifact ID is a piece of build-time information and should be utterly irrelevant during runtime. BTW, artifact IDs can change, dependencies be re-packaged into uber JARs via Maven Shade or Maven Assembly plugins etc. What you want to do is simply bad design. You should refactor your libraries or find another way to differentiate them from each other.
FWIW, you can solve your problem also during build time by applying native AspectJ aspects to selected artifacts using binary weaving, creating new woven artifacts which can replace the original ones. The AspectJ Maven plugin does that for you, if configured correctly. For Gradle have a look at Freefair.
Update: About 7 years ago, I answered another question involving binary weaving of input JARs. It is a more complex multi-module scenario and if you read the whole answer, you are also going to find a link to a GitHub repository with a complete MCVE. Just replace the the Maven plugin org.codehaus.mojo:aspectj-maven-plugin:1.7 by dev.aspectj:aspectj-maven-plugin:1.13, because the MojoHaus version only supports up to Java 8 and misses some features compared the Aspectj.dev version.

How to manually add dependencies to Gradle's MavenPom/MavenPublication?

I am working on a plugin. This plugin gets attached to a project that does not apply the java plugin nor the java-library plugin but which should functionally "look" like a Java project[1]. Which means that it should publish a POM including dependencies. The exact dependencies are known and have been collected in a Configuration.
However, I cannot figure out how to manually attach dependencies to the MavenPublication such that they make it into the published pom (aside from directly editing the pom xml).
MavenPublication shadowMavenPublication = publishingExtension.getPublications().create( "mavenShadowArtifacts", MavenPublication.class );
// `shadowPublishArtifact` is a class defined in the plugin
shadowMavenPublication.artifact(
shadowPublishArtifact.getFile(),
(mavenArtifact) -> {
mavenArtifact.setClassifier( shadowPublishArtifact.getClassifier() );
mavenArtifact.setExtension( shadowPublishArtifact.getExtension() );
}
);
So at this point I have the MavenPublication and added my custom artifact to it. Internally this MavenPublication contains a number of "dependencies" as instances of MavenDependency. E.g. DefaultMavenPublication#runtimeDependencies, DefaultMavenPublication#apiDependencies, ... But those are things defined on internal-only contracts.
Using just public APIs, how can I add dependencies to get added to the pom?
P.S. As a bonus, answer the question on the Gradle forums and get points there too! :D
P.S.S. These dependencies come from another project (hibernate-core) in a multi-project build. The user has configured those dependencies themselves. I just "consume" those dependencies with a series of "dependency substitutions". That "source project" defines some exclusions to its dependencies. How can I access those exclusions do be able to transfer them to the dependencies I am creating for this copy project (hibernate-core-jakarta)?
Thanks!
[1] Its a long back-story, but the gist is that this plugin integrates the JakartaTransformer. The project is completely generated using the transformer. The tasks added by those 2 plugins cause problems.
MavenPublication class has pom property - You need to construct (or provide in Your plugin some API for that purpose) pom with all necessary dependencies. It will be published alongside with artifact.
As far as I know, dependencies are attached to the POM by evaluating the configurations of a software component: MavenPublication.from(SoftwareComponent) (source: DefaultMavenPublication).
The idea would be to provide a customized software component. This is only possible through a custom plugin, according to Creating and publishing custom components.

Why is it not recommended to define maven artifact repository URL in pom file? (Azure context, artifact source)

My team is migrating our code to an Azure environment and Microsoft's own article on the subject describes how to use Maven in an Azure environment:
https://learn.microsoft.com/en-us/azure/devops/java/labs/mavenpmvsts/?view=vsts
One of Maven's best practices is to avoid defining repository elements within the pom file and use a repository manager configured within the settings.xml instead.
The Microsoft article instructs otherwise: they say to add the repository url right in the pom file.
I would have been okay with it if the repository element was defined only in the distributionManagement section, but that is not the case. The article defines the url in a repositories element outside of the distribution context.
My understanding of the repository element of the pom.xml file is that it overrides the source of artifacts used for fetching dependencies. The problem I see defining this in the pom file is that it could have adverse effects depending how the library is being reused.
Use case example:
1) Shared library is created with repository url defined in pom
2) Shared library is deployed. POM file containing url and JAR file are published.
3) Artifact repository is moved, renamed or copied, url is changed.
4) Later on, a new application using that shared library is created, but uses the new repository url. The URL in the application pom is now different from the one in the shared library's previously published pom.
Because Maven uses a dependency graph and inheritance, what I would expect to happen is that when we build the new application:
1) maven will read the application pom file and begin exploring the dependency graph by downloading pom files for each of the application's dependencies from the URL found in the application's pom. In this case, the only download is the shared library's pom.
2) maven will explore transitive dependencies and read the shared library's pom. Reading the shared library's pom, the repository section will take precedence over the application's pom in the context of the shared library's dependencies. The shared library's dependencies poms would be downloaded from the old URL.
3) maven will continue like that and download all the pom files until the dependency tree has been built.
4) depending on project configuration, maven will go through the graph it built to download the jars and etc using the same rules.
In this use case, maven would download artifacts from both the old source and the new source. If the old source no longer exists or isn't accessible in this build context, the project cannot be built. This is why it's best to avoid setting repository urls in a pom file.
Or so I thought.
I wrote a scripted demo with local repositories to show my team exactly what would happen and to my surprise, even though Maven does download the shared library's pom file containing a different repository url, the repository tag does not seem to be overriding the one from the application being built. Logs show all artifacts being downloaded from the source specified in the "top" application pom.
So my question to Stack Overflow is two fold:
1) Why am I wrong? Did I misunderstand Maven's inheritance, dependency graph building and behavior?
2) Shouldn't Maven download the shared library's dependencies from the url specified in the repository tag, if specified? I'm sure there are some cases where the artifacts must come from a private repo. (ex: org.geotools)
3) Does anyone have experience setting up Maven on Azure? Did you follow Microsoft's guide or found a way to move repository urls to your settings.xml in an Azure environment?

Maven - duplicating dependency with different types/classifiers in dependency management

I'm looking at a project's POM and its dependency management section lists the same artifact 3 times - each time with different classifiers/types. What does this help you achieve?
Specifically, the dependency in question is the test module of the project. Its 3 occurrences in the POM have the following form:
default scope, default type, default classifier
default scope, test-jar type, default classifier
default scope, test-jar type, test-sources classifier
Dependency management helps organizing your dependencies in a central place. In your case, that particular artifact is going to be used in different forms in different modules:
Plain dependency
Share the test code with the module that depends on it (test dependency) - Same for 3

Resources