difference of artifactId and name in maven POM - java

I am new to maven and I'm confused about the difference between the artifactId and name.
What I know is that artifactId is the name of the artifact you are creating. I know that artifactId together with the groupId is use to uniquely identifies an artifact. So what is <name> purpose in POM. like the pom below I got from a site there is an artifactId and at the same time a <name>.
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>simple-parent</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<name>Multi Chapter Simple Parent Project</name>

You are correct that the artifactId helps identify the project.
The name is simply a human-readable "friendly" name. It is not required for a basic setup.
From the Maven documentation,
artifactId: The artifactId is generally the name that the project is known by. Although the groupId is important, people within the group will rarely mention the groupId in discussion ... It, along with the groupId, create a key that separates this project from every other project in the world (at least, it should :) ). Along with the groupId, the artifactId fully defines the artifact's living quarters within the repository.

The groupId, artifactId and version form a composite unique identifier (or coordinate) for this project. Each of these values has a fairly rigid naming convention that allows well organized groups, artifacts and versions.
The name is simply a readable name for the project and does not need to be unique or comply to the same conventions (so it can contain spaces and other characters).

The name is used for the project used by maven to build the artifact, while the artifact-id is used to identify the artifact that will be built.
For example:
This pom file definition for the rsts ear file:
Causes the rsts-ear project to be imported into Eclipse:
But creates the rsts_ear artifact in the nexus:
This means that the artifact-id, not the name, is referenced to include the artifact in the build as part of another artifact.

Related

Is there a way to use jars with no-compliant name? [duplicate]

My project depends on Netty Epoll transport. Here is dependency:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty.version}</version>
<classifier>${epoll.os}</classifier>
</dependency>
The auto-generated module name for this dependency is:
netty.transport.native.epoll
And as the native keyword is reserved in Java 9 I can't add this module as a dependency to my project:
module core {
requires netty.transport.native.epoll;
}
Due to:
module not found: netty.transport.<error>
Additionally the jar tool --describe-module reports the following:
Unable to derive module descriptor for:
netty-transport-native-epoll-4.1.17.Final-SNAPSHOT-linux-x86‌_64.jar
netty.transport.native.epoll: Invalid module name: 'native' is not a
Java identifier
Are there any workarounds? (except "release correct netty artifact", of course).
EDIT:
As the quick fix for maintainers - you can add next line to build:
<manifestEntries>
<Automatic-Module-Name>netty.transport.epoll</Automatic-Module-Name>
</manifestEntries>
The solution to this seems to be:-
A way possible to uninterruptedly using the same artifact name with a new(different) module name could be by packaging META-INF/MANIFEST.MF of the artifact with an attribute Automatic-Module-Name which governs the name of the module to be used by the module descriptor when converted as an automatic module.
OR
Artifact owners can add module declarations using module-info.java to their JAR. (this could result in a slow bottom-up migration)
Since the module declaration defined in the specs as:
A module declaration introduces a module name that can be used in
other module declarations to express relationships between modules. A
module name consists of one or more Java identifiers (§3.8) separated
by "." tokens.
Intersetingly the declarations suggests -
In some cases, the Internet domain name may not be a valid package
name. Here are some suggested conventions for dealing with these
situations:
If the domain name contains a hyphen, or any other special character
not allowed in an identifier (§3.8), convert it into an underscore.
If any of the resulting package name components are keywords (§3.9),
append an underscore to them.
If any of the resulting package name components start with a digit, or
any other character that is not allowed as an initial character of an
identifier, have an underscore prefixed to the component.
But keep in mind as you do so that Underscore is a keyword in Java9
int _; // is would throw an error on javac based out of JDK9
int _native; // works fine
From now on you can also use this small Maven plugin to automatically modify the manifest file in a Scala jar in your local Maven repo: https://github.com/makingthematrix/scala-suffix
Under the link you will find the overview of the whole issue and what you need to add to you pom.xml, but I was asked to also explain here, so here it goes:
As it was mentioned already, Java does not recognize suffixes in modules names like _2.13 as version numbers and treat them as integral parts of modules names. So, when your project tries to use a class from the Scala dependency, it will look for your.scala.dependency.2.13 instead of just your.scala.dependency, it will fail to do it, and it will crash.
To fix this on your side (i.e. without any action from the library's creator) add this to the <plugins> section of your pom.xml:
<plugin>
<groupId>io.github.makingthematrix</groupId>
<artifactId>scala-suffix-maven-plugin</artifactId>
<version>0.1.0</version>
<configuration>
<libraries>
<param>your-scala-dependency</param>
</libraries>
</configuration>
<executions>
<execution>
<goals>
<goal>suffix</goal>
</goals>
</execution>
</executions>
</plugin>
where your-scala-dependency is a name of your Scala dependency without the version suffix (if there are more than one, just add them with more <param> tags). This should be the same as artifactId in your <dependency> section.
The plugin modifies the dependency's JAR file in your local Maven repository. It opens the jar, reads META-INF/MANIFEST.MF and adds to it a line:
Automatic-Module-Name: your-scala-dependency
If the property Automatic-Module-Name already exists, the plugin does nothing - we assume that in that case the dependency should already work. This prevents the plugin from modifying the same JAR file more than once.

Renaming Java class with Maven Archetype

Is it possible to rename a java class using Maven?
I'm using the Maven Archetype to generate new projects based on my model. I can set a new groupId, artifactId, and packages for each new project.
This is the current pom.xml inside target.
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
<packaging>jar</packaging>
So, when I want to create a project Banana (artifactId) inside com.foo (groupId) , it's pretty possible. All I need to do is run: mvn archetype:generate (...arguments like groupId, artifactId, version)
It will generate a new project based on my archetype, renaming its packages, groupId, artifactId. But I also want to rename some java classes, thus:
ArchetypeApplication.java should be renamed to BananaApplication.java!
Is there some way to do that?
You can only specify a class name if the archetype supports this feature. For example: zk-archetype-theme defines the "theme-listener-class" property for this.

How does nexus-staging-maven-plugin use <scm> information?

I have a single Git repository that contains several Maven modules, using Maven inheritance and Maven aggregation. That is, in the root directory, there is a parent POM, that defines some modules, each of which use that root POM as their parent.
<project>
…
<groupId>io.example</groupId>
<artifactId>parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<packaging>pom</packaging>
…
<scm>
<connection>scm:git:https://bitbucket.org/example/foobar.git</connection>
<developerConnection>scm:git:https://bitbucket.org/example/foobar.git</developerConnection>
<url>https://bitbucket.org/example/foobar</url>
</scm>
…
<modules>
<module>foo</module>
<module>bar</module>
</modules>
…
I recently found out that Maven will append the module path to the <scm><url> value for each module (foo and bar above). For example, the foo submodule would get an SCM URL of https://bitbucket.org/example/foobar/foo.
So should each of my modules redeclare the <scm> section, so that the submodule POMs have the same SCM URL as the parent POM? How does the Nexus Staging Maven Plugin use this SCM information, anyway?
I have also cross-posted this at Sonatype.
Regarding your initial question in the title: It does not use it given the code provided at github. When you search for 'scm' in all .java files you have zero hits. Of course they could do some weird tricks like building the String like "s" + "c" + "m" or it is hidden in some third party dependency or...
Still I think besides an offical answer, this is the best any outsider can tell.

Require akka in module-info.java [duplicate]

My project depends on Netty Epoll transport. Here is dependency:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty.version}</version>
<classifier>${epoll.os}</classifier>
</dependency>
The auto-generated module name for this dependency is:
netty.transport.native.epoll
And as the native keyword is reserved in Java 9 I can't add this module as a dependency to my project:
module core {
requires netty.transport.native.epoll;
}
Due to:
module not found: netty.transport.<error>
Additionally the jar tool --describe-module reports the following:
Unable to derive module descriptor for:
netty-transport-native-epoll-4.1.17.Final-SNAPSHOT-linux-x86‌_64.jar
netty.transport.native.epoll: Invalid module name: 'native' is not a
Java identifier
Are there any workarounds? (except "release correct netty artifact", of course).
EDIT:
As the quick fix for maintainers - you can add next line to build:
<manifestEntries>
<Automatic-Module-Name>netty.transport.epoll</Automatic-Module-Name>
</manifestEntries>
The solution to this seems to be:-
A way possible to uninterruptedly using the same artifact name with a new(different) module name could be by packaging META-INF/MANIFEST.MF of the artifact with an attribute Automatic-Module-Name which governs the name of the module to be used by the module descriptor when converted as an automatic module.
OR
Artifact owners can add module declarations using module-info.java to their JAR. (this could result in a slow bottom-up migration)
Since the module declaration defined in the specs as:
A module declaration introduces a module name that can be used in
other module declarations to express relationships between modules. A
module name consists of one or more Java identifiers (§3.8) separated
by "." tokens.
Intersetingly the declarations suggests -
In some cases, the Internet domain name may not be a valid package
name. Here are some suggested conventions for dealing with these
situations:
If the domain name contains a hyphen, or any other special character
not allowed in an identifier (§3.8), convert it into an underscore.
If any of the resulting package name components are keywords (§3.9),
append an underscore to them.
If any of the resulting package name components start with a digit, or
any other character that is not allowed as an initial character of an
identifier, have an underscore prefixed to the component.
But keep in mind as you do so that Underscore is a keyword in Java9
int _; // is would throw an error on javac based out of JDK9
int _native; // works fine
From now on you can also use this small Maven plugin to automatically modify the manifest file in a Scala jar in your local Maven repo: https://github.com/makingthematrix/scala-suffix
Under the link you will find the overview of the whole issue and what you need to add to you pom.xml, but I was asked to also explain here, so here it goes:
As it was mentioned already, Java does not recognize suffixes in modules names like _2.13 as version numbers and treat them as integral parts of modules names. So, when your project tries to use a class from the Scala dependency, it will look for your.scala.dependency.2.13 instead of just your.scala.dependency, it will fail to do it, and it will crash.
To fix this on your side (i.e. without any action from the library's creator) add this to the <plugins> section of your pom.xml:
<plugin>
<groupId>io.github.makingthematrix</groupId>
<artifactId>scala-suffix-maven-plugin</artifactId>
<version>0.1.0</version>
<configuration>
<libraries>
<param>your-scala-dependency</param>
</libraries>
</configuration>
<executions>
<execution>
<goals>
<goal>suffix</goal>
</goals>
</execution>
</executions>
</plugin>
where your-scala-dependency is a name of your Scala dependency without the version suffix (if there are more than one, just add them with more <param> tags). This should be the same as artifactId in your <dependency> section.
The plugin modifies the dependency's JAR file in your local Maven repository. It opens the jar, reads META-INF/MANIFEST.MF and adds to it a line:
Automatic-Module-Name: your-scala-dependency
If the property Automatic-Module-Name already exists, the plugin does nothing - we assume that in that case the dependency should already work. This prevents the plugin from modifying the same JAR file more than once.

Why sometimes dependency not contain version property in pom.xml?

I am a newbie of Maven, currently reading Hadoop source code, and found something interesting in some pom.xml files:
Some of the dependency node do not contain version node at all.
Question: why is it like this?
for instance, this pom.xml.
Because specific version of dependency in parent pom.xml file
https://github.com/apache/hadoop/blob/trunk/pom.xml
Reference: https://maven.apache.org/guides/introduction/introduction-to-the-pom.html
As I commented at first, a pom file can have a parent (via inheritance) and such a parent may provide some governance and harmonization across all of its children. A classic case is to provide versioning for certain dependencies via a dependencyManagement section.
is used by POMs to help manage dependency information across all of its children. If the my-parent project uses dependencyManagement to define a dependency on junit:junit:4.0, then POMs inheriting from this one can set their dependency giving the groupId=junit and artifactId=junit only, then Maven will fill in the version set by the parent. The benefits of this method are obvious. Dependency details can be set in one central location, which will propagate to all inheriting POMs.
The mentioned pom has indeed a parent pom:
<parent>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-project-dist</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../../hadoop-project-dist</relativePath>
</parent>
Which in chain has another parent pom file which defines several dependencies as part of its dependencies management section.
If you really want to check the effective (merged) pom your build is using, you could run:
mvn help:effective-pom -Doutput=effective-pom.xml
And the maven-help-plugin will produce an additional pom as specified by the command above, merging the current pom file and all of its anchestors.
In Maven you can inherit from parents folder in order to merge or inherit some properties. This can be the version of the modules. Usually you have a "super" POM in the root folder of your project and you put there all the commons dependencies in order to controll them in an easier way. I.e. If you must change one module version, you only need to change in the "super" POM and not in each POM inside each subfolder that need it. If you need more information about POM inheritance the documentation has a couple of useful examples.
https://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Project_Inheritance

Categories

Resources