How to provide artifact upload settings in maven - maven

I am using artifactory for artifacts management .To upload my artifacts to the server i have below lines added to my pom.xml
<distributionManagement>
<repository>
<id>e512209f3d01</id>
<name>e512209f3d01-releases</name>
<url>http://server-cicd-01-ubt:8081/artifactory/ext-release-local</url>
</repository>
<snapshotRepository>
<id>e512209f3d01</id>
<name>e512209f3d01-snapshots</name>
<url>http://server-cicd-01-ubt:8081/artifactory/ext-snapshot-local</url>
</snapshotRepository>
</distributionManagement>
but i do not want these settings to be in pom.xml.Is there any way i can define in global setting.xml. What will be the syntax for that.

In a similar need, we implemented a super pom, which is a single file component (pom.xml only) that declares all common properties and settings to be used by all components developed in our R&D group.
We mostly define common properties like dependencies versions strings and also the section is there.
Every component needing this needs to declare the super pom as its parent:
<parent>
<groupId>com.mycompany</groupId>
<artifactId>super-pom</artifactId>
<version>1.0.1</version>
</parent>
This works very well for us for managing 100s of components in the system, which all share common properties.
You can add may common elements like plugins, dependency management etc.
I hope this helps.

Related

Anybody able to use GitLab Maven Repository Group Level Endpoint?

I have a group on GitLab with two projects, and I wish to use the group level maven endpoint so that each project can reference one repository URL for the group instead of each project needing to know the specific project repositories.
However, I cannot seem to get it to work. I can build a library and push its artifact to the repository, and another project can find it with the project level maven endpoint. However, when I use the group level repository URL as described in the document, replacing my-group with my group, the build fails because it "Could not find artifact". Has anybody got this to work?
<repositories>
<repository>
<id>gitlab-maven</id>
<url>https://gitlab.com/api/v4/groups/my-group/-/packages/maven</url>
</repository>
</repositories>
For anybody with the same problem, I was able to make it work with the group ID.

Is it possible to specify in a parent pom exactly where I want to deploy a site?

In the team I work for, I need to deploy site artifacts to a maven repo in the following format:
http://therepo/site/${project.groupId}/${project.artifactId}/${project.version}
Because I'm a big fan of doing things in a DRY manner, I have put this in my parent pom within a distributionManagement tag. Like so:
<distributionManagement>
<site>
<id>team-site</id>
<name>Team Snapshot Site Repository</name>
<url>dav:http://therepo/snapshot/site/${project.groupId}/${project.artifactId}/${project.version}</url>
</site>
</distributionManagement>
This seems reasonable except that the maven site plugin will automatically add the project artifact id to the end of the URL if the URL is provided by a parent pom. This behavior is documented here: https://maven.apache.org/plugins/maven-site-plugin/usage.html#Deploying_a_Site
Obviously this isn't what I want to happen. As a result of this behavior, my site URL effectively becomes:
http://therepo/site/${project.groupId}/${project.artifactId}/${project.version}/${project.artifactId}
Is there a way to suppress this behavior? Or do I have to put a distributionManagement tag in every single project?
Thanks!

Avoid referencing parent pom in maven multi module project

My multi module project is made of public (open source) and private (undisclosed) modules. I need to create a master-all pom file referencing master-public and master-private, so that some plugins & commands are aware of all projects (e.g. cobertura). master-all has thus to be private as it references master-private.
The problem is that master-public should reference its parent master-all which is private, so users of public modules only won't be able to build them:
<groupId>group</groupId>
<artifactId>master-public</artifactId>
<parent>
<groupId>group</groupId>
<artifactId>master-all</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
Nesting master-public in master-private could be a solution for maven, but will be a mess for git.
Is there a clean way to do this?
You can have your master-private reference your master-public. But in my experience, it is best to keep them completely separate. Eventually, the master-public will be tuned more to open source, possibly deploying to Maven Central, while the master-private will deploy to your internal repository and possible have some special settings that only make sense in your enterprise environment. Copy whatever you absolutely need from your master-private to your master-public and disconnect the two.

Maven Multi Module Project

I havent used Maven extensively
Presently have 5 different maven projects , Each has a different pom.xml. As of now there is dependency relationship between them , each one points to other in < dependency > if needed.
Presently the thing we dont like are
When we release a child projectA , then we need to manually modify all projects having projectA as a dependency to use new version. Saw Maven has a version plugin , not sure how that will help.
As a solution I want to have a cleaner organization between poms , and possible avoid above issue.
What i thought is ( may be incorrect )
Where fat arrow represents Parent Child relationship and a thin arrow represents sub-module. But this does not seem to be working, see code and errors below
Child Project 2 pom
<groupId>ChildProject2</groupId>
<artifactId>ChildProject2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>Parent</groupId>
<artifactId>Parent</artifactId>
<version>${parent.version}</version>
<relativePath>../Parent/pom.xml</relativePath>
</parent>
<dependencies> ... </dependencies>
ChildProject2 - Error
Project build error: Non-resolvable parent POM: Failure to transfer Parent:Parent:pom:${parent.version} from http://repo1.maven.org/maven2 was
cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. Original error:
Could not transfer artifact Parent:Parent:pom:${parent.version} from/to central (http://repo1.maven.org/maven2): Illegal character in path at index 45:
http://repo1.maven.org/maven2/Parent/Parent/${parent.version}/Parent-${parent.version}.pom and 'parent.relativePath' points at wrong local POM
Parent pom
<groupId>Parent</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<parent.version>0.0.1-SNAPSHOT</parent.version>
</properties>
<modules>
<module>../ChildProject2</module>
<module>../ChildProject1</module>
</modules>
<dependencies> ... </dependencies>
GrandParent2 pom
<groupId>GrandParent2</groupId>
<artifactId>GrandParent2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<grandparent2.version>0.0.1-SNAPSHOT</grandparent2.version>
</properties>
<modules>
<module>../Parent</module>
</modules>
<dependencies>... </dependencies>
ParentMain.java
public class ParentMain {
public static void main(String[] args) {
DocumentFactory df = new DocumentFactory();
ChildProject1Main cp1 = new ChildProject1Main();
ChildProject2Main cp2 = new ChildProject2Main();
}
}
ParentMain - Errors
ChildProject1Main cannot be resolved to a type
ChildProject1Main cannot be resolved to a type
I am currently using Maven Version 2.2.1 (open to upgrading if this can be solved using upgraded maven version)
One of the comments below says can solve this using " CI tools out there such as Jenkins and TeamCity" .. any pointer (examples) how to solve this using Maven ( and or Hudson )??
What am i doing wrong , how to get best design for such project dependencies
The first question I thought of when I saw this diagram was, "Why would the business logic have any kind of dependencies on submodules?" Two thoughts sprung to mind, and I'll go through each of them and what you shouldn't be doing to repeat these.
Tightly coupled code. This manifests itself in code duplication or the large class/method smell.
You want your code to be modular, such that a project only depends on what it needs to in order to compile and run without error.
Illogical code hierarchy. This (eventually) manifests itself as circular dependencies, or dependencies that suddenly go missing when <exclude> blocks show up.
You want the lines of what depends on what to be explicit, such that your code hierarchy is well laid out.
I'm going to take your arrows in one cardinality to mean that a project depends on another, so it makes sense that the UI and CLI depend on the Business Logic to function. It also makes sense that Business Logic can depend on the children modules to do some other function not quite related to the core.
What doesn't make sense is that these children models also depend on Business Logic. The children modules should be unique enough that they do not need to depend on anything from Business Logic; if they do, then perhaps they should live there instead.
As for the versioning - there are CI tools out there such as Jenkins and TeamCity that can aid you with that problem. The thrust would be to have that set up in such a way that it occurs independent of human intervention/error.
How do I tell Maven to use the latest version of a dependency?
Take a look at the above thread. I like the answer by Adam Gent to use the versions plugin to update versions in your poms in jenkins. I agree with him that maven and continuous deployment are a particularly poor match.
So use that and a simple parent pom for any shared configuration (plugins, dependencies, etc) but don't make them multi module projects and version and release the parent pom as an independent thing.

Do I need to have a Parent declaration in my POM.xml?

I've declared my project as a pom.xml to define the parent, and it triggers a reactor build of all the included modules. Everything builds fine and works as expected. It builds in the right order, all the tests run correctly, and I get my expected output.
One of the projects is a shared library. I don't want to add a <parent> declaration here, so I didn't. It all still works.
My Question: do I need to bother adding a parent project declaration in any of my sub-projects? What are the pros and cons of having a two-way relationship between the projects? If I don't add the declarations, am I going to make it harder later when something stops working?
Rephrased into a single question: why bother with <parent> configuration in module pom.xml files?
Your question is related to the difference between Project Inheritance vs. Project Aggregation. The <parent> reference defines the inheritance relationship. The <modules> section in the parent pom.xml defines the aggregation. They are different.
If you do not have the <parent> configuration in the module pom.xml, it will not inherit the parent pom.xml configuration. So let's say you define the version of a dependency in the parent pom in the <dependencyManagement> section, the module pom.xml without parent reference will not inherit that. Or if all your child modules need to use a common library, you can define the dependency in the parent pom.xml. However, the module pom.xml without the parent reference will not inherit that dependency either.
For details, please check out Project Inheritance vs Project Aggregation
It depends on how you configure your build. If you have a correctly configured parent pom, basic information like version and groupid can be shared between your projects.
You can define the project wide configuration information that should be shared in all the modules in the project. For example:
<modelVersion>4.0.0</modelVersion>
<groupId>groupd.id</groupId>
<artifactId>artifact.id</artifactId>
<packaging>pom</packaging>
<version>version</version>
With that in place, you do not have duplicate that information in the module projects. The same information can be referenced like so:
<parent>
<groupId>group.id</groupId>
<artifactId>artifact.id</artifactId>
<version>version</version>
</parent>
Remember that the parent pom can be used to shared more information than specified above. You can do dependency management, plugin management and even define re-usable profiles.

Resources