Maven: How to deploy with deploy-file and custom wagon - java

I'm trying to use a custom maven wagon extension to deploy a jar to my own repository. Can I somehow configure in settings.xml that it recognizes the custom url scheme to be used with the specific wagon or do I have to always modify pom files to contain the wagon extension?
There doesn't need to be a base pom or any pom available when using the deploy-file. Settings.xml is the only place which is guaranteed to be there, but I can't figure out how to use it to define extensions.

OK, ok, a correction: you cannot define the <build> element inside a <profile> defined in settings.xml. You could activate the profile in settings.xml, but define it in your base-pom.
Sorry, the only other way I could think of (probably what are you looking for), is to copy the extension jar directly under $M2_HOME/lib. All $M2_HOME/lib/*.jar are put in the classpath, so this must virtually have the same effect as an <extension>.
The extension however is better, because you can more easily control which version of the extension is used (e.g. trough the base-pom).
OK just try copying the extension jar under
$M2_HOME/lib

I don't know if the comment above by Brian Fox is still valid in 2013. But in the end I had to create a minimal pom.xml in the directory where I tried to upload the artifact to enable the wagon build extension.
I had to add groupId, artifactId and version to the pom.xml so that Maven would not complain although I provided them to the deploy-file goal on the commandline (I guess deploy-file would only care about the commandline parameters though):
<project 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>your-groupId</groupId>
<artifactId>your-artifactId</artifactId>
<version>your-version</version>
<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.4</version>
</extension>
</extensions>
</build>
</project>
With this simple "pom.xml" in place I could execute the deploy-file finally using scp as the protocol:
mvn deploy:deploy-file -Durl=scp://shell.sourceforge.net:/home/project-web/... -DrepositoryId=repoId -Dfile=my-file.jar -DgroupId=your-groupId -DartifactId=your-artifactId -Dversion=your-version -Dpackaging=jar

You need to add the wagon extension to your top level pom.xml. Most environments have a corporate one at the top of all their projects (best practice), so this generally isn't too painful for individual developers -- they just inherit from the corporate pom.
<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-scm</artifactId>
<version>1.0-alpha-7-SNAPSHOT</version>
</extension>
<extension>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-manager-plexus</artifactId>
<version>1.0-beta-3-SNAPSHOT</version>
</extension>
<extension>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-svnexe</artifactId>
<version>1.0-beta-3-SNAPSHOT</version>
</extension>
</extensions>
</build>
<distributionManagement>
<site>
<id>my.svn.server</id>
<url>scm:svn:https://username#svn.apache.org/svn/root/module</url>
</site>
</distributionManagement>
When you register your provider, it also registers the protocol pattern as well I believe. You can see a full list of the existing providers here.
I believe it is the getScmType() method that registers the extension, but I'm not 100% certain.
/** {#inheritDoc} */
public String getScmType()
{
return "git";
}
The link to the Git provider's source can be found here.

siddhadev is right, but there are few additional things...
(I'd put this in a comment but I don't have enough reputation)
You can keep your JARs cleanly separated by putting them under:
$M2_HOME/lib/ext
You need all of the dependencies, so do something like:
cd ~/.m2/repository/org/apache/maven/wagon/wagon-ssh-external/2.2
cp wagon-ssh-external-2.2.jar $M2_HOME/lib/ext
cp wagon-ssh-external-2.2.pom pom.xml
mvn dependency:copy-dependencies -DoutputDirectory=$M2_HOME/lib/ext

Related

Error Code 400 when trying to (maven) deploy to github packages using github actions

I am struggling with the (seemingly) simple task of deploying a maven project to github packages using a github actions workflow. First of all, here's the error I am getting in the maven deploy phase:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on project [project name]: Failed to retrieve remote metadata [groupId]:[artifactId]:1.0-SNAPSHOT/maven-metadata.xml: Could not transfer metadata [groupId]:[artifactId]:1.0-SNAPSHOT/maven-metadata.xml from/to github (https://maven.pkg.github.com/[username]/[repository]): Failed to transfer file https://maven.pkg.github.com/[username]/[repository]/[groupId as path]/[artifactId]/1.0-SNAPSHOT/maven-metadata.xml with status code 400 -> [Help 1]
(Info: I replaced unneccessary and/or private concrete information with general terms in [brackets])
Most likely, the actual maven-metadata.xml file is not the problem because I have already seen warnings like "could not upload checksum" with status 400 before. I guess that maven-metadata.xml is just the first file it fails on, but probably I am completely wrong with this assumption, please tell me if so.
Probably the most important file is the workflow yaml file:
name: Deploy SNAPSHOT (develop)
on:
push:
branches:
- develop
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v1
- name: Set up JDK 11
uses: actions/setup-java#v1
with:
java-version: 11
- name: Maven Deploy
env:
GITHUB_USERNAME: x-access-token
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: mvn --settings settings.xml -B -e -Dmaven.wagon.http.pool=false clean deploy
Also quite important: the maven settings.xml file:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<activeProfiles>
<activeProfile>github-packages</activeProfile>
</activeProfiles>
<profiles>
<profile>
<id>github-packages</id>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>github</id>
<name>GitHub [username] Apache Maven Packages</name>
<url>https://maven.pkg.github.com/[username]</url>
</repository>
</repositories>
</profile>
</profiles>
<servers>
<server>
<id>github</id>
<username>${env.GITHUB_USERNAME}</username>
<password>${env.GITHUB_TOKEN}</password>
</server>
</servers>
</settings>
(Info: same goes for values in brackets as before)
And lastly, the parent pom.xml of my maven project:
<?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>[groupId]</groupId>
<artifactId>[artifactId]</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
[child modules]
</modules>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.release>11</maven.compiler.release>
</properties>
<dependencies>
[my dependencies]
</dependencies>
<distributionManagement>
<repository>
<id>github</id>
<name>GitHub [username] Apache Maven Packages</name>
<url>https://maven.pkg.github.com/[username]/[repository]</url>
</repository>
</distributionManagement>
</project>
Maybe it's also important to say that the GitHub repository belongs entirely to me and therefore I should have all admin rights on it.
Things I've tried:
I have done some research by now and I found that my issue seems to be not uncommon. Although, from all solutions I've found so far, not one has worked.
Official GitHub documentation for setting up workflows
To start of, I used this site as my reference.
This StackOverflow Question
I mostly stuck to all the advice I found in this question and in the answers to it.
This other StackOverflow Question about nexus deploys
The accepted answer of this question provides a checklist. I tried to check that all the bullet points work for me, although I wasn't able to validate everything. I did not find any issue based on this checklist.
This question on the GitHub community forum
The error displayed in this question looks very much like the error I am getting, still the proposed solution did not fix anything for me.
This Answer on a similar GitHub community forum question
This answer suggested using a personal access token instead of the GITHUB_TOKEN. I tried that and it changed nothing.
What I need
Of course I'd be happy if someone can show me what the exact issue of my case is, but it does not need to be that specific. I am trying to set up the most basic pipeline possible and I currently don't want to do more than just deploy a maven snapshot repository to github packages (with github actions). So, if anyone can show me how to do this properly in general, that's also fine. Thanks!
I kinda figured it out myself, but the result is very dissatisfying. The main problem here is:
Note: GitHub Packages does not support SNAPSHOT versions of Apache Maven. Make sure you disable SNAPHOT in your ~/.m2/settings.xml file.
(Source)
So, it seems like GitHub Packages does not support the construct of maven snapshot repositories, which are otherwise very practical. My plan was to set up a workflow that deploys a new SNAPSHOT on the package registry when a push to develop happens. Maven snapshot repositories do not require unique version numbers for deploys, which means I could have built a new version for every push, but the actual dependency version stays fixed. Everyone could then easily try out the latest state of my develop branch, simply by including the fixed snapshot version in their pom files.
Now, how to fix my issue:
Because GitHub packages does not support snapshot repositories, you will have to remove the keyword "SNAPSHOT" from the value in the project.version tag in your pom file. Basically you can put every other version description there, but now it is unique. However if you remove all SNAPSHOT keywords, the workflow should properly deploy a package to the GitHub package registry, at least it worked for me.
If anyone knows a way to "hack" around this SNAPSHOT issue, please tell me. Otherwise this is the only working solution I've found so far.

Errors upgrading from eclipse-update-site to eclipse-repository Maven packaging

I am using Tycho and Maven to build an eclipse update site containing several plugins. Everything worked happily when I packaged it as an eclipse-update-site, but I'm getting errors now that I've switched to eclipse-repository.
My projects looks like
com.mycompany.plugin/
src/things.java
pom.xml
com.mycompany.plugin.feature/
feature.xml
pom.xml
com.mycompany.updatesite/
category.xml (formerly site.xml)
pom.xml
This page indicates that the maven packaging "eclipse-update-site" is deprecated in favor of "eclipse-repository". Accordingly, I updated my update site's pom.xml to look like (approximately):
<project>
<tycho.version>0.26.0</tycho.version>
<groupId>mygroup</groupId>
<artifactId>artifactId</artifactId>
<version>1.0.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-repository-plugin</artifactId>
<version>${tycho.version}</version>
</plugin>
</plugins>
</build>
<packaging>eclipse-repository</packaging>
</project>
I also renamed my site.xml file to category.xml as suggested by this post and this post. I did not make any other changes to category.xml (formerly site.xml), so it looks like:
<?xml version="1.0" encoding="UTF-8"?>
<site>
<feature url="features/com.mycompany.plugin.feature_0.1.0.qualifier.jar" id="com.mycompany.plugin.feature" version="0.1.0.qualifier">
<category name="com.mycompany"/>
</feature>
<category-def name="com.mycompany" label="MyPlugin"/>
</site>
The maven build marches along happily, building all of my plugins and features. When it tries to build the repository, it fails, saying:
[ERROR] Failed to execute goal org.eclipse.tycho:tycho-p2-repository-plugin:0.26.0:assemble-repository
(default-assemble-repository) on project com.mycompany.updatesite: Could not assemble p2 repository:
Mirroring failed: No repository found at file:/mypath/com.mycompany.updatesite/target/. -> [Help 1]
Clearly I'm missing something, but I can't figure out what.
Which phases of maven are you running?
I encountered the same problem when switching from eclipse-update-site to eclipse-repository and using just the package phase. However, it worked with install.
Or more specifically instead of
mvn clean package
I used
mvn clean install
I hope this helps you too.

Generating Java classes from XSD maven dependency in maven with JAXB (or others)

I have a data model stored in the Maven repo as an XSD file. My goal is to create a jar with all the Java classes representing this model. I want to use maven and JAXB to do this.
I know about the maven-jaxb2-plugin (codehouse-mojo and java-net, not sure yet how they differ) but I don't see a way to use XSD from the maven dependency as an input. Do I have to write my own plugin to do this?
It doesn't have to be JAXB if there is a better tool to it.
Disclaimer: I'm the author of the maven-jaxb2-plugin.
Check the documentation, it's right there. See Specifying What To Compile - Specifying URLs, filesets and Maven artifact resources.
Example:
<configuration>
<schemas>
<!--
Compiles a schema which resides
in another Maven artifact.
-->
<schema>
<dependencyResource>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin-tests-po</artifactId>
<!-- Can be defined in project dependencies or dependency management -->
<version>${project.version}</version>
<resource>purchaseorder.xsd</resource>
</dependencyResource>
</schema>
</schemas>
</configuration>
You can also use catalogs to rewrite schema URLs to Maven artifact resources.
Example:
REWRITE_SYSTEM "http://schemas.opengis.net" "maven:org.jvnet.ogc:ogc-schemas:jar::!/ogc"
This will rewrite an URI http://schemas.opengis.net/ows/2.0/owsAll.xsd to maven:org.jvnet.ogc:ogc-schemas:jar::!/ogc/ows/2.0/owsAll.xsd. This will reference the ogc/ows/2.0/owsAll.xsd resource in ogc-schemas JAR artifact.
As far as I know, these features are unique to the maven-jaxb2-plugin.

How te rename EAR artifact with Maven

I have a project Maven ear modules, and i like to rename the ear from ProjectIt-4.1.0.ear to ProjectIt-4_1_0.ear in fact to have a version like that : x_y_z to resolve a deployement contraints
You can define a custom property holding your key with your own separtor between major, minor and maintenance version.
Then you can use that property in the build name of your artifact:
<project>
...
<properties>
<custom.version>x_y_z</custom.version>
</properties>
...
<build>
<finalName>${project.artifactId}-${custom.version}</finalName>
</build>
</project>
Meanwhile, I wouldn't advice such a method of shipping artifacts version, because it would not fit the common version syntax. You can read more about Semantic Versionin in semver.

How to read properties file from one project into another project?

I have two java projects A and B, If I have a credentials.properties file in A and I want to access the same properties file in project B, Is there a way I can achieve this?
The two projects are maven build.
Try this:
<resource>
<directory>${other projects dir}/src/main/resources</directory>
<includes>
<include>*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
Give the path as a full path
Keep the property file in the class path of B and set Project B as a dependency to project A.
Commiting cleartext passwords into your source control is normally a bad idea...
How about using a shared Maven profile in your settings file? ($HOME/.m2/settings.xml):
<settings>
..
<profiles>
<profile>
<id>credentials</dev>
<activeByDefault>true</activeByDefault>
<properties>
<password1>XXXXX</password1>
<password2>YYYYY</password2>
..
..
</properties>
</profile>
..
</profiles>
..
</settings>
This approach is more Maven friendly and encryption is supported.
If you use Jenkins to build your code, you can use a plugin to manage the settings file centrally:
How to manage maven settings.xml on a shared jenkins server?
Your project can still have a default value, the key point is that the real passwords are set externally to files under source control.

Categories