How to use Sesame Rio with maven-shade-plugin? - sesame

When I try to use Sesame Rio in a standalone Java application packaged with the maven-shade-plugin, I get
Exception in thread "main" org.openrdf.rio.UnsupportedRDFormatException: Did not recognise RDF format object N-Triples (mimeTypes=application/n-triples, text/plain; ext=nt)
at org.openrdf.rio.Rio.lambda$unsupportedFormat$0(Rio.java:630)
at org.openrdf.rio.Rio$$Lambda$1/736709391.get(Unknown Source)
at java.util.Optional.orElseThrow(Optional.java:290)
at org.openrdf.rio.Rio.createParser(Rio.java:119)
at org.openrdf.rio.Rio.createParser(Rio.java:137)
at org.openrdf.repository.util.RDFLoader.loadInputStreamOrReader(RDFLoader.java:318)
at org.openrdf.repository.util.RDFLoader.load(RDFLoader.java:222)
at org.openrdf.repository.util.RDFLoader.load(RDFLoader.java:105)
at org.openrdf.repository.base.AbstractRepositoryConnection.add(AbstractRepositoryConnection.java:255)
Running the application from Eclipse succeeds. How can I fix this?

The RDF format handlers in Rio are implemented as services, so the service descriptors have to be included in the shaded JAR. This is achieved with the ServicesResourceTransformer:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
More info:
Dependency on sesame-runtime with shade onejar packaging
sesame-assembly-2.8.2.pom

Related

Maven: downloading files from url

Can I download some files from http while maven lifecycle? any plugin?
If the file is a Maven dependency, you could use the Maven Dependency Plugin which has a get goal.
For any file, you could use the Antrun plugin to call Ant's Get task.
Another option would be the maven-download-plugin, it has been precisely created to facilitate this kind of things. It's not very actively developed and the documentation only mentions an artifact goal that does exactly the same thing as dependency:get but.. If you look at the sources, you'll see that is has a WGet mojo that will do the job.
Use it like this in any POM:
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<!-- the wget goal actually binds itself to this phase by default -->
<phase>process-resources</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>http://url/to/some/file</url>
<outputFileName>foo.bar</outputFileName>
<!-- default target location, just to demonstrate the parameter -->
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Key benefits of this plugin are caching of the download and checking against a signature, such as MD5.
Note that this answer has been heavily updated to reflect changes in the plugin as noted in the comments.
Seems like wagon-maven-plugin from CodeHaus allows to download files over HTTP (though this is not is original goal).
Here is an example downloading GlassFish zip before integration tests:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>download-glassfish</id>
<phase>pre-integration-test</phase>
<goals>
<goal>download-single</goal>
</goals>
<configuration>
<url>http://download.java.net</url>
<fromFile>glassfish/3.1/release/glassfish-3.1.zip</fromFile>
<toDir>${project.build.directory}/glassfish</toDir>
</configuration>
</execution>
</executions>
</plugin>
The maven-antrun-plugin is a more direct solution:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>download-files</id>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<!-- download file -->
<get src="http://url/to/some/file"
dest="${project.build.directory}/downloads/"
verbose="false"
usetimestamp="true"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
I'd like to add a few thing about the download-maven-plugin:
Project is now hosted on GitHub https://github.com/maven-download-plugin/maven-download-plugin
Its releases are available on Maven Central, and the SNAPSHOTs are available on the oss.sonatype.org snapshot repository
Compared to other suggestions mentioned here, the download-maven-plugin adds the following interesting feature: caching of files (to avoid always redownloading big files) and signature verification to make sure download got the right bits.
If available, wget can be used directly with exec-maven-plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>wget</executable>
<arguments>
<argument>http://example.com/file.zip</argument>
<argument>destination.zip</argument>
</arguments>
</configuration>
</plugin>
You can use the download-single goal in the wagon plugin. Here is an example to download an HTML page (notice that the URL have to be split in a "directory" url and a "file name")
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>validate</phase>
<goals><goal>download-single</goal></goals>
<configuration>
<url>http://www.mojohaus.org/wagon-maven-plugin</url>
<fromFile>download-single-mojo.html</fromFile>
<toFile>[my dir]/mojo-help.html</toFile>
</configuration>
</execution>
</executions>
</plugin>

How to make jetty-maven-plugin deploy a war that is retrieved from a repository?

I'm setting up an integration test module for a good sized web project. The integration test module is separated from the web project itself, and it has it's own pom.
The idea is to use the maven-soapui-plugin to send requests and verify the response. Setting up the soapui-plugin is no hassle. However, I'm having trouble with figuring out how I can tell the jetty-maven-plugin to deploy a war from a remote repository.
If I have understood correctly, the jetty-maven-plugin has a property called '<webApp>/<webApp>' which lets me specify the war file to deploy. The problem is that the war file is not present in the module itself.
I have heard that I can use the maven assembly plugin to retrieve the war from a repository via the projects artifactId, but I am yet to figure out how I would go about doing so.
Here's a summary of what I want:
Retrieve a specific war from a repository or the like, in example via its artifactId.
Deploy this war to the jetty-maven-plugin (goal deploy-war?)
get maven-soapui-plugin to run tests and report the results back in the integration-test phase.
I am pretty sure I've got step 3 covered, but I am very unsure how to achieve step 1 and 2.
Any help is greatly appreciated
It is maybe possible to use dependency:copy to retrieve the war, unpack it and to get the whole thing working with the maven jetty plugin, but this would be hacky and kinda ugly. A cleaner solution would be to use the Maven Cargo plugin and this is my suggestion. Below, a sample POM showing how to retrieve a WAR artifact using its coordinates and how to deploy it on an embedded Jetty container using Cargo:
<dependencies>
<dependency>
<groupId>war group id</groupId>
<artifactId>war artifact id</artifactId>
<type>war</type>
<version>war version</version>
</dependency>
...
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<configuration>
<!-- Container configuration -->
<container>
<containerId>jetty6x</containerId>
<type>embedded</type>
</container>
<!-- Configuration to use with the container or the deployer -->
<configuration>
<deployables>
<deployable>
<groupId>war group id</groupId>
<artifactId>war artifact id</artifactId>
<type>war</type>
<properties>
<context>war context</context>
</properties>
</deployable>
</deployables>
</configuration>
<!-- Don't wait, execute the tests after the container is started -->
<wait>false</wait>
</configuration>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
Finally, just bind the soapui plugin on the integration-test phase.
I'm doing the same thing, John, but I took a different approach with the Jetty plugin. I think the end result is the same. I'm developing an integration-test suite to run against several web service WARs. I'm using dependency:copy in the package phase and then a list of <contextHandler/>s configured for maven-jetty-plugin:
<project>
…
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-wars</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/wars-to-be-tested</outputDirectory>
<stripVersion>true</stripVersion>
<artifactItems>
…
<artifactItem>
<groupId>groupId</groupId>
<artifactId>artifactId</artifactId>
<version>version</version>
<type>war</type>
</artifactItem>
…
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.1.3.v20100526</version>
<configuration>
…
<contextHandlers>
…
<contextHandler implementation="org.mortbay.jetty.plugin.JettyWebAppContext">
<war>${project.build.directory}/wars-to-be-tested/artifactId.war</war>
<contextPath>/context</contextPath>
</contextHandler>
</contextHandlers>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>stop</goal>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I would prefer to declare the various wars as dependencies and then use dependency:copy-dependencies to set up the wars-to-be-tested directory; this would allow the Maven reactor to figure out that it needs to build my integration-test module after the wars it'll be testing. The problem I ran into was that the Jetty plugin thought that I wanted to "overlay" all of the wars that were listed as dependencies (a concept that I'd never even heard of until I saw it happen); I don't know if allowing that to happen would have hurt anything, but I didn't like it, so I went with the dependency:copy method.
This is just an alternative to using Cargo. I'll be looking into that myself, but I just wanted to provide another way of doing it.

Maven-assembly-plugin: custom jar filenames

I use the assembly plugin to create several jars with some classes in it. I need custom names for the resulting jars: app_business.jar app_gui.jar core.jar etc.
Currently I have to following configuration:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<finalName>app_business</finalName>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<attach>true</attach>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
an the assembly.xml file:
<assembly>
<id>app_business</id>
<formats>
<format>jar</format>
</formats>
<baseDirectory>target</baseDirectory>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>org/xyz/**</include>
</includes>
</fileSet>
</fileSets>
</assembly>
this creates a file app_business.jar which is perfect. But i have no idea how to create my other files. The option appendAssemblyId doesn't help me, as it creates filenames in the format AppName-app_business.jar. I really need the exact filesname app_business.jar.
Any Idea? Thank you very much!
You can move the configuration element below the execution element of the plugin declaration. This means the configuration will only be applied to that execution. You can then add additional executions of the assembly plugin for your other assemblies.
Here is an example of the modified configuration with two executions, each referencing a different assembly:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-business-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<finalName>app_business</finalName>
<descriptors>
<descriptor>src/main/assembly/business-assembly.xml</descriptor>
</descriptors>
<attach>true</attach>
</configuration>
</execution>
<execution>
<id>make-gui-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<finalName>app_gui</finalName>
<descriptors>
<descriptor>src/main/assembly/gui-assembly.xml</descriptor>
</descriptors>
<attach>true</attach>
</configuration>
</execution>
</executions>
</plugin>
With this configuration, two additional jars (app _business.jar and app _gui.jar) will be created in the target directory, though be aware if you install the project, only the last artifact assembled will be installed (this could of course be a problem).
To avoid this you would need to change the appendAssemblyId properties to true. The closest you can get in this case is to change the finalNames to "app" and the IDs to "gui" and "business", resulting in app-gui.jar and app-business.jar being packaged and all artifacts being installed.
The standard maven plugins are meant for general, repetitive work. They gather all information from the POM and they are smart (in the sense that you don't need to configure much).
If you need special tasks, then I suggest to use the ant plugin which allows you to embed a piece of Ant code in the POM. This allows you to run the jar task.

Can maven sign not only produced jar, but also dependencies

I managed to create main jar, copy dependencies to a single directory, the only step left is to sign all jars.
I can sign my own produced jar as a part of jar:sign, but how do i sign dependencies?
Thanks
Here are a couple of options:
Use the Maven ant task to run jarsigner from the JDK against all the dependencies.
Use the webstart plugin which can sign all your JARs, even if you aren't using it for the purpose of JNLP-izing your app. I'm using it to actually JNLPize one app.
Look at what the webstart plugin source is doing to iterate over all dependencies and sign them and start a new Maven Plugin/Mojo that does the same thing, sans JNLP.
Onejar your app and its dependencies and just sign that.
add to plug-in config <archiveDirectory>target</archiveDirectory>
If you are using maven-jar-plugin, you can specify which single jar to sign using the "jarPath" setting. The following configuration causes the jar-with-dependencies file to be signed instead of the dependency-less jar file:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>sign</goal>
</goals>
</execution>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- NOTE: The secret key is in shared version control. The
password is in shared version control. This IS NOT
SECURE. It's intended to help avoid accidentally
loading the wrong class, nothing more. -->
<jarPath>${project.build.directory}/${project.build.FinalName}-${project.packaging}-with-dependencies.${project.packaging}</jarPath>
<keystore>${basedir}/keystore</keystore>
<alias>SharedSecret</alias>
<storepass>FOO</storepass>
</configuration>
</plugin>
If you want to sign both, I don't know how to do that with maven-jar-plugin, so you may need to look into the other options mentioned above.
One can also create a single JAR using the maven-assembly-plugin.
Together with the other suggestion by Eric Anderson (of signing another JAR) one can then sign this assembled JAR (instead of the original JAR). Note that the order of the plugin definitions matters here.
It is assumed that sign.keystore.file etc are set elsewhere (e.g. in a profile).
<build>
<plugins>
<!-- It seems that maven-assembly-plugin must be declared before the maven-jar-plugin,
so that it is executed first in the package phase,
and then the signing of the packaged jar can succeed. -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifestEntries>
<!-- ... -->
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<jarPath>${project.build.directory}/${project.build.FinalName}-${project.packaging}-with-dependencies.${project.packaging}</jarPath>
<keystore>${sign.keystore.file}</keystore>
<type>${sign.keystore.type}</type>
<storepass>${sign.keystore.storepass}</storepass>
<alias>${sign.keystore.alias}</alias>
<verify>true</verify>
<verbose>false</verbose>
<removeExistingSignatures>true</removeExistingSignatures>
</configuration>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<!-- <addClasspath>true</addClasspath> -->
</manifest>
<manifestEntries>
<!-- ... -->
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>

How to get Maven to run war:exploded but not war:war

I have a Maven pom that uses <packaging>war</packaging>. But actually, I don't want build the war-file, I just want all the dependent jars collected and a full deployment directory created.
So I'm running the war:exploded goal to generate the deploy directory:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<webappDirectory>target/${env}/deploy</webappDirectory>
<archiveClasses>true</archiveClasses>
</configuration>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
The trouble is, the war file still gets built. Is there a simple way of having <packaging>war</packaging> execute the war:exploded goal instead of the war:war goal?
Or is there another simple way to do this?
The solution is quite simple. You need to override the default execution of the war plugin to disable it and add your own execution (for exploded):
<pluginManagement>
<plugins>
<plugin><!-- don't pack the war -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<id>default-war</id>
<phase>none</phase>
</execution>
<execution>
<id>war-exploded</id>
<phase>package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
According builtin lifecycle bindings for war packaging in package phase war:war mojo is called.
You can call previous 'prepare-package' phase - all actions will be performed and after that call mojo war:exploded
mvn prepare-package war:exploded
The results will be the same as yours but no war created.
I would like to upgrade onto #Michael Wyraz answer and just include install skip settings in case if someone executes mvn clean install build on top level of multimodule project and one of sub-module is web application.
This stands inside war module:
<profiles>
<profile>
<id>war_explode</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>default-war</id>
<phase>none</phase>
</execution>
<execution>
<id>war-exploded</id>
<phase>package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
Without install skip build fails as it tries to install war into .m2 folder. Error message looks like this:
[INFO] --- maven-install-plugin:2.4:install (default-install) # *** ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.4:install (default-install) on project ***: The packaging for this project did not assign a file to the build artifact -> [Help 1]
Executing mvn clean install -P war_explode with this settings (enclosed in maven profile named war_explode) it finishes build without error.
The only way I can think of to do what you want is to set use pom packaging (or create a custom packaging) and bind the required goals from the war packaging to the relevant phases of the lifecycle. If you go for pom packaging you can use define the war:war execution in a profile to allow you to package it, but you'll need to use the build-helper-maven-plugin attach-artifact goal to attach the war to the pom.
Note with this approach if you want to use any other war-specific processing it may cause you problems.
The lifecycle bindings for war packaging are listed in the Introduction to The Build Lifecycle (see the "Default Lifecycle Bindings - Packaging ejb / ejb3 / jar / par / rar / war" section).
To bind the relevant plugin executions to the pom packaging you would do as follows:
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>process-resources</id>
<phase>process-resources</phase>
<goals>
<goal>resources</goal>
</goal>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compile-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goal>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>process-test-resources</id>
<phase>process-test-resources</phase>
<goals>
<goal>testResources</goal>
</goal>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goal>
</execution>
</executions>
</plugin>
<!-- package not wanted, install and deploy already defined for pom packaging-->
<!--define war:war execution in a profile in case it is needed-->
As far as I know (I'm still new to maven) this is not possible. The only default lifecycle you can skip is 'test'. In order to get to the deploy you have to package. You can read all about the default lifecycle order of execution here: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference