In Maven how do I copy files using the wagon plugin? - maven

Summary: How do I copy some generated files into a webserver (eg IIS or Apache) directory using Maven?
Details:
I have a working application that builds in Maven. I've managed to get it building using the webstart-maven-plugin which produces all the needed files (.jar and .jnlp) in a directory target/jnlp. It also creates a zip file with them all in at target/foo-1.0.zip.
At the moment the webstart plugin does not have a deploy goal - the request for it has ended up on the FAQ (question 3). It may be implemented in future, but the suggestion for the time being is to use wagon-maven-plugin.
I've never used Wagon. To start with I'd like to just copy the files to a local directory served up by a webserver. Later I'd like to copy them remotely, probably using ftp. Can someone give an example to what I need to add to the pom.xml to get the local copy working (and hopefully an ftp example too?). I can't find it in the documentation. From reading I think I might also need the Wagon Maven File Provider but as this seems to have almost no documentation I'm not sure.

Wagon providers are only there to provide additional network protocol supports (such as FTP).
If you want to copy file to a webserver (local or distant) you can use Maven upload plugin :
...
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-upload-plugin</artifactId>
</plugin>
...
In parent pom :
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-upload-plugin</artifactId>
<version>1.1</version>
<configuration>
<resourceSrc>
${project.build.directory}/${project.build.finalName}.${project.packaging}
</resourceSrc>
<resourceDest>${jboss.deployDir}</resourceDest>
<serverId>${jboss.host}</serverId>
<url>${jboss.deployUrl}</url>
</configuration>
</plugin>
And to configure parameters in a smart way, I use maven profiles (in parent pom) :
<profiles>
<!-- local deployment -->
<profile>
<id>developpement</id>
<properties>
<jboss.host>localhost</jboss.host>
<jboss.deployDir>appli/jboss-4.0.4.GA/server/default/deploy/</jboss.deployDir>
<jboss.deployUrl>file://C:/</jboss.deployUrl>
</properties>
</profile>
<!-- distant deployment -->
<profile>
<id>validation</id>
<properties>
<jboss.host>ENV_val</jboss.host>
<jboss.deployDir>/home/envval/jboss/server/default/deploy/</jboss.deployDir>
<jboss.deployUrl>scp://PROJECT_LAN_HOST</jboss.deployUrl>
</properties>
</profile>
</profiles>
I've created an "ant launcher", to use it by clicking under Eclipse ant view :
<target name="copy war to JBoss local" description="Copy war to local JBoss">
<maven goal="upload:upload" options="-Pdeveloppement" />
</target>
But you can simply run it on a command line :
mvn upload:upload -Pdeveloppement
EDIT : By the way, for distant deployment, you may need a login password for scp to work. You have to add them to you Maven settings.xml file :
<settings>
...
<servers>
<server>
<id>ENV_val</id>
<username>login</username>
<password>password</password>
</server>
</servers>
...
</settings>
EDIT: You'll need to add the Atlassian repository:
<pluginRepositories>
<pluginRepository>
<id>Atlassian</id>
<url>https://maven.atlassian.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
EDIT: depending upong the remote protocol you'll have to add wagon extensions, see Uploading a directory using sftp with Maven

In the end I didn't use the Maven upload plugin - it seemed a bit limited and not part of the main maven distribution. I used the maven wagon plugin as suggested. Here is the simplest possible pom that I could make that worked. Hopefully others will find it useful, as I couldn't find anything similar easily.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0-beta-3</version>
<configuration>
<fromDir>${project.build.directory}/jnlp</fromDir>
<includes>*</includes>
<url>file://c:/inetpub/wwwroot</url>
<toDir>jnlp</toDir>
</configuration>
</plugin>
For remote distributions, you just change the URL type, and possibly add wagon extensions as necessary.

Related

GitLab Package Registry as Maven Artifactory

I am trying to setup a GitLab project as the remote maven repository for all my other projects using GitLab Maven Package Registry. I have uploaded all dependency jar files to the package registry. All the jar files have been uploaded using maven's deploy feature. I am trying now to setup this project's package registry as the remote maven repository for all my other projects. The necessary repository settings is provided in the package registry itself, in each individual artifact page, as follows:
<repositories>
<repository>
<id>gitlab-maven</id>
<url>https://<gitlab_instance>/api/v4/projects/<project_id>/packages/maven</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitlab-maven</id>
<url>https://<gitlab_instance>/api/v4/projects/<project_id>/packages/maven</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
<url>https://<gitlab_instance>/api/v4/projects/<project_id>/packages/maven</url>
</snapshotRepository>
</distributionManagement>
However, even after adding this in the pom.xml of other projects, their builds are failing citing dependency unavailability. It seems that this project's package registry is unreachable from other projects. What am I doing wrong here? Are there any additional steps I need to undertake?
Did you amend the settings.xml which you are using when calling a maven command?
There something like this:
<servers>
<server>
<id>gitlab-maven</id>
<configuration>
<httpHeaders>
<property>
<name>Job-Token</name>
<value>${env.CI_JOB_TOKEN}</value>
</property>
</httpHeaders>
</configuration>
</server>
</servers>
should be present. To use the settings.xml with your specific maven command, you can specify it by typing:
mvn -s settings.xml package
You need to add an authenticate header(personal token, CI job token, or deploy token).
This is the doc: Adding the GitLab Package Registry as a Maven remote

Can't discover maven.restlet.com

When i build my project the jars for org.restlet.jee, as a dependency for apache-camel, are missing.
[WARNING] The POM for org.restlet.jee:org.restlet.ext.spring:jar:2.2.2 is missing, no dependency information available
So i added in Nexus a new proxy repository for http://maven.restlet.com/.
After adding there is an error during the discovery process:
Remote strategy prefix-file on M2Repository(id=maven-releases) detected invalid input, results discarded: Prefix file does not start with expected "## repository-prefixes/2.0" header, refusing to load the file.
Is there any solution how i can use the restlet repository with Nexus?
Edited: my pom.xml
<distributionManagement>
<repository>
<id>releases</id>
<name>Internal Releases</name>
<url>http://xxx:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Internal Snapshots</name>
<url>http://xxx:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<extensions>true</extensions>
<configuration>
<serverId>deployment</serverId>
<nexusUrl>http://xxx:8081/nexus/</nexusUrl>
</configuration>
</plugin>
...
</plugins>
</build>
The prefix file message has to do with automatic routing. The site at maven.restlet.com doesn't support this feature. It's nothing to worry about though, see here for an explanation:
https://support.sonatype.com/entries/30645946-
Check to make sure the proxy repository you just added is a member of the group repository you've configured maven to use in your settings.xml file.
If that isn't the problem you can get information about this problem by using the technique described here:
https://support.sonatype.com/entries/21433982
I've had the same problem recently with restlet repo and proxying it through nexus. The problem is it doesn't accept proxying, you'll get this information by using techniques mentioned by rseddon.
To solve the problem you have to update your proxy repository configuration in nexus by setting a user agent in the optional http request settings to something being used by browsers, e.g. Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0.
It should help.

OSGi: how to use PuTTY scp with maven-bundle-plugin

I want to deploy my maven compiled OSGi bundle to my remote OSGi repository. I'm on Windows 7 and use the maven-bundle-plugin (2.3.7) from eclipse. The repository is on linux and is accessed over ssh.
I have configured in settings.xml to use plink and pscp (Putty tools) to do the ssh work.
In <distributionManagement> I set the repository url, which starts with scpexe://
The maven-deploy goal works fine and uploads the jar files and metadata.xml to the repository.
Now I also want the OBR metadata to be produced and uploaded. I thus add in the configuration of the maven-bundle-plugin, <remoteOBR>my-repository</remoteOBR> (which is the same ID as the repository in <distributionManagement>.
When executing deploy, (after the maven deploy phase finishes successfully), I get the error.
[ERROR] Failed to execute goal
org.apache.felix:maven-bundle-plugin:2.3.7:deploy (default-deploy) on
project bootstrapper: Transfer failed: Exit code: 1 - 'scp' is not recognized as an
internal or external command, operable program or batch file.
-> [Help 1]
This means that the maven-bundle-plugin does not use the pscp command as specified in settings.xml, but rather "scp", which is not available on the path.
How can I configure the maven-bundle-plugin to upload the OBR data using PuTTY's pscp?
I eventually found a working solution:
don't use the external ssh tool (PuTTY), but only the maven-internal ssh/scp implementation
thus, use wagon-ssh (not wagon-ssh-external)
add username, private key location and passphrase to settings.xml (sadly, cannot use pageant, but must hardcode my passphrase in settings.xml (beuh) )
So the POM looks like (note, scp:// protocol is used for the url)
<project>
...
<distributionManagement>
<repository>
<id>my-repository</id>
<url>scp://repo.myserver.com/path/to/repo/</url>
</repository>
</distributionManagement>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<configuration>
...
<remoteOBR>my-repository</remoteOBR>
</configuration>
</plugin>
</plugins>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.5</version>
</extension>
</extensions>
</build>
...
And settings.xml (which is located at C:\Users\myUsernameOnWindows\.m2\)
<settings>
<servers>
<server>
<id>my-repository</id>
<username>myUsernameOnRepo</username>
<privateKey>C:/path/to/private/key/id_rsa</privateKey>
<passphrase>myPrivateKeyPassphrase</passphrase>
</server>
</servers>
</settings>

Maven deploy .jar to network location

How can I deploy a .jar to a network path? I'm looking at maven-deploy-plugin and other examples and keep finding things about deploying to tomcat, glassfish and ftp. My needs are simpler. I only need to deploy to a network path.
Bonus: After running a network path, is it possible to run console commands on an external windows command prompt?
The maven-deploy-plugin is intended to deploy an artifact to a repository which means usually to a repository manager (Artifactory, Nexus, Archiva etc.). The things you are talking about can be handled by the tomcat6- or tomcat7-maven-plugin which support the things you need. Other containers like Glassfish can be handled by cargo2-maven-plugin. I'm not aware of a up-to-date glassfish-maven-plugin only this one maven-glassfish-plugin which looks out of date (Take a look here).
If you like making deployments via ftp you can use the following configuration for the maven-deploy-plugin:
<project>
...
<distributionManagement>
<repository>
<id>ftp-repository</id>
<url>ftp://repository.mycompany.com/repository</url>
</repository>
</distributionManagement>
<build>
<extensions>
<!-- Enabling the use of FTP -->
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>1.0-beta-6</version>
</extension>
</extensions>
</build>
...
</project>
<settings>
...
<servers>
<server>
<id>ftp-repository</id>
<username>user</username>
<password>pass</password>
</server>
</servers>
...
</settings>
But this is in contradiction to the idea of Maven.
You can try to use the deploy-file goal of the maven-deploy-plugin to see if this would be option to deploy to a network path. I'm not sure if this will work.

Setting up Maven to allow deployment to different repositories easily

I'm currently working in an environment where I define the rules for a lot of people. We currently use Hudson and Artifactory, and I want to evaluate if the switch to Jenkins and Nexus are worth the migration cost (but this is not the question).
To eval it, I have setup Maven, Jenkins, and Nexus locally, and I try to find a setup to use as much of the previous setup, so that I can compare the solutions. The problem here is:
When I use an existing POM and build and deploy it through Jenkins, it is automatically deployed to our old environment.
I have then tried to define the deploymentManagement section in my .settings file in Maven, but this is not allowed (see Configuring Maven, there
Note: the installation and user configuration cannot be used to add shared project information - for example, setting or company-wide.
I could of course copy the whole, and change the distributionManagement inside each POM, but I would like to use the same (not a copied) example in different installations.
Our current root POM contains the following section:
<distributionManagement>
<repository>
<uniqueVersion>false</uniqueVersion>
<id>company-central</id>
<name>Company central maven respository</name>
<url>https://company.com/artifactory/libs-releases</url>
</repository>
<snapshotRepository>
<id>company-snaps</id>
<name>company-snapshots</name>
<url>https://company.com/artifactory/libs-snapshots</url>
</snapshotRepository>
<downloadUrl>https://company.com/artifactory/libs-releases</downloadUrl>
</distributionManagement>
What is the easiest way to use the same POM, but to deploy it to different repository managers?
PS: I have read set up maven pom file for different deployment scenarios and don't like it (in my context), Deploying Maven artifact to multiple repositories with different settings is really a different question. Multiple deployments in maven is an interesting approach, but I would have to modify a lot of POMs only for this purpose.
I'm on a similar team, providing tools to others. We have our parent POM (not the settings.xml) set up like the below. The prod version is active unless one of my team members adds -DuseTestRepo=true to the mvn command line. You could experiment with changing the activation to look for a particular file that exists only on the Jenkins server (for example). I've also wondered if Maven interpolates properties in repo URLs. If it does, you could do <url>${my.remote.repo}/releases</url> and define my.remote.repo in settings.xml. Haven't tried that one.
<profiles>
<profile>
<id>test-repository</id>
<activation>
<property>
<name>useTestRepo</name>
<value>true</value>
</property>
</activation>
<properties>
</properties>
<distributionManagement>
<repository>
<!-- ... -->
</repository>
<snapshotRepository>
<!-- ... -->
</snapshotRepository>
</distributionManagement>
</profile>
<profile>
<id>prod-repository</id>
<activation>
<property>
<name>!useTestRepo</name>
</property>
</activation>
<properties>
</properties>
<distributionManagement>
<repository>
<!-- ... -->
</repository>
<snapshotRepository>
<!-- ... -->
</snapshotRepository>
</distributionManagement>
</profile>
As to delivering (deploying) your experimental parent POM - you would be deploying it to your test Nexus repo, right? And none of your developers are accessing that, only you. So Artifactory will contain the real com.company:corporate-parent:1.0 POM, and Nexus the com.company:corporate-parent:1.0 that contains the changes you require for your testing.
I would also consider changing the local repo in your settings.xml so you don't mix artifacts from the two remote repos.

Resources