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

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>

Related

Pushing artifacts to the Nexus using Jenkins maven-release-plugin

In my Jenkins dashboard, I'm using maven-release-plugin (v0.16.2) to perform a maven release to Nexus repository. I have some issues while using this plugin.
Issue 1:
As shown in the image, it uses <project_name>-<release_version> as the SCM default tag. But I want to change it as v<release_version> value. Therefore, I have added the following change into my project pom.xml file's plugin section.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<tagNameFormat>v#{project.version}</tagNameFormat>
</configuration>
</plugin>
</plugins>
</build>
But still, it uses the aforementioned default tag. Is there any other configuration I have to do in Jenkins or pom.xml file?
Issue 2:
I have configured my pom.xml file with distributionManagement section to push my built artifact to the Nexus repository as follows.
<distributionManagement>
<repository>
<id>releases</id>
<name>Release Distribution Repository</name>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
</distributionManagement>
With this configuration, Jenkins pushes all the project built artifacts (packaging JAR artifact + dependency XML artifacts in M2) to the given Nexus repository successfully. But in my case, I want to deploy only the JAR file to the Nexus repository (excluding other dependency XML files). Is it possible to do with this Jenkins maven release plugin? Deploy only a specific file or directory?

How to deploy a maven web application in ftp?

I am building a web project using spring framework and maven. I want to deploy it using ftp.
For this I have included the apache weagon :
<distributionManagement>
<repository>
<id>ftp-repository</id>
<url>ftp://ftp.xxxxx.com</url>
</repository>
</distributionManagement>
<build>
<!-- FTP TRANSFER -->
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>1.0-beta-5</version>
</extension>
</extensions>
and I have also created a file settings.xml
<settings>
<servers>
<server>
<id>ftp-repository</id>
<username>user</username>
<password>pass</password>
</server>
</servers>
</settings>
But when I execute mvn deploy I get the following error:
Authentication failed, Password not specified for the repository ftp-repository.
Is this the correct way to deploy an app?
What else should I do to deploy it successfully?
For completeness sake, I have had this issue when i tried to connect to an sftp server using the default ftp 'wagon'. When I changed the artefactId to wagon-ssh (also see this link) the messages started to make more sense.
In other words; the error message is not very helpful in this particiular case.

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.

how to add external jar to maven webapp project

I have a Spring roo project (basically a maven project). I want to add dropbox sdk to the project, problem is it's not in maven. I added the following files
<dependency>
<groupId>com.dropbox</groupId>
<artifactId>dropbox-sdk</artifactId>
<version>1.3.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/dropbox-java-sdk-1.3.1.jar</systemPath>
</dependency>
It solved the compile error, but when i run the project, in Spring Tool Suite, the jar files are not added to war lib folder. How do I make maven add my external jar files to my the war lib folder?
I don't want to install the jar in maven since, I have to install it in all the machines that uses the project
I finally found a neat solution, which is a lot easier to implement. You add an in-project repository inside the java project and link to it in the pom.
You add an in-project repository in maven like this:
<repository>
<id>in-project</id>
<name>In Project Repo</name>
<url>file://${project.basedir}/libs</url>
</repository>
Then create a folder structure in the root folder of your project that looks something like this
/groupId/artifactId/version/artifactId-version.jar
and add the dependency as you would normally do.
This approach has the least amount of code and work required, and if that library ever gets add into a maven repository you can always remove your in-project repository.
There is a much easier solution, which is set webResource in the plugin. By the solution, you can add any files of your local disk to the war! A sample is as below,
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>api</warName>
<webResources>
<resource>
<directory>libs/</directory>
<targetPath>WEB-INF/lib</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
The best way to resolve this issue is to add these local jar files to WEB-INF/lib folder. You will find all these jars packaged in your final war file then.
I don't recommend this approach, but you could add some POM configuration to install the 3rd-party dependency in a separate profile:
<profiles>
<profile>
<id>install-dependencies</id>
<build>
<plugins>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>install-dropbox-sdk</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>com.dropbox</groupId>
<artifactId>dropbox-sdk</artifactId>
<version>1.3.1</version>
<file>src/main/lib/dropbox-java-sdk-1.3.1.jar</file>
<packaging>jar</packaging>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>build</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>com.dropbox</groupId>
<artifactId>dropbox-sdk</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
</profile>
</profiles>
There are two profiles here: install-dependencies and build. The first installs the dropbox-sdk dependency into your Maven repository and needs to be run once on every machine as follows:
mvn -Pinstall-dependencies validate
The second is enabled by default, and adds the Dropbox SDK as a dependency.
To be honest though, this isn't much better than running
mvn install:install-file -Dfile=src/main/lib/dropbox-java-sdk-1.3.1.jar -DgroupId=com.dropbox -DartifactId=dropbox-sdk -Dversion=1.3.1 -Dpackaging=jar
on every machine.
The other downside of this approach is that you'll have to add all dependencies of the dropbox-sdk to your build as well- whereas if it is done properly by adding the JAR and a POM to a repository server, then Maven will calculate the transitive dependencies properly.
I recommend creating a "third party" repository in a Maven repository server such as Nexus or Artifactory, and uploading the jar to there. Even though that means putting the jar into Maven, at least with a repository server it is available to anyone who will be building your application.
change the lib path to :
src/main/webapp/WEB-INF/lib
in pom.xml:
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/xxxx.jar</systemPath>
The steps described in this site are pretty simple, and they work well enough:
https://mythinkpond.com/2010/10/02/adding-custom-jars-under-web-inflib-in-a-maven-project/
Create a “lib” folder under your project like this: “\src\main\webapp\WEB-INF\lib”
Copy needed “jars” etc that you want included inside your WAR bundle folder.
Invoke your maven build as you normally do. I use “mvn install”, which creates builds the war file.
I know I am really late but I was wondering on why you would not put in the jar in the local repo in the .m2 file and add a reference to the pom from there ?

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

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.

Resources