Suppose I have a set of n Java libraries each with a conf and a resources folder and then I have a Java project X that depends on some of these n Java libraries, how do I make it so that when X is built, all the dependent conf and resources folders are copied and merged in the dist folder. No - I don't want them to be embedded in the jars.
Obviously, there will be issues with duplicate filenames, but let's assume all files have distinct names.
Edit: An additional and related question: How do it so that project X can detect the conf and resources during development phase of all the dependent projects without needing to copy them over to project X's folder. For example, I'd like Netbeans to be able to find these resources that the referenced libraries use when I click "Run" on X's main method.
Edit2: Here's a hypothetical example of a project setup:
**Library 1:** Image Processing
conf: Processing configurations, log4j
resources: Training sets, etc.
**Library 2:** Machine Learning
conf: Training parameters, log4j
resources: Dependent C++ batch files (i.e. system calls)
**Library 3:** Reporting Tool
resources: Reporting templates
**Library 4:** Text Mining Toolkit
conf: Encoding, character sets, heuristics
resources: Helper PHP scripts
**Executable Project 1: **
Uses Library 1 to process images
Uses Library 2 to do machine learning on processed images
Uses Library 3 to make reports
**Executable Project 2: **
Uses Library 4 to do text mining
Uses Library 2 to do machine learning on collected textual information
Uses Library 3 to make reports
We can assume Executable Projects 1 and 2 can use different parameters for their constituent libraries once deployed.
Take a look at the maven-dependency-plugin which can copy the deps and copy them to particular location.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
<destFileName>optional-new-name.jar</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/wars</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
I see the following in your example. Let me use Library 1 as an example.
Library 1: Image Processing
conf: Processing configurations, log4j
resources: Training sets, etc.
You have library 1 which contains processing configuration which sounds to me like a runtime configuration. This mean it should be part of the created jar (src/main/resources the location for such things). The same is for log4j configuration. Just put it into the jar (src/main/resources of the project.
Now comming to resources: Training set. If you make a separate maven project which contains a training set so this will produce a single artifact and can later be used to integrate that into the Example 1. If you have several training sets you can create different artifacts and use them as usual dependency or use the maven-dependency-plugin (or may be the maven-remote-resources-plugin) to use them in your projects.
With this setup you can deploy Library 1 into your local repository and of course into a repository manager and use it as a dependency.
You can use the same approach to handle Library 2, 3 etc.
May be you can take a look at the maven-remote-resource-plugin (I'm not sure if this helps).
Related
TL; DR
Maven's Resources plugin doesn't seem to respect excludes elements in the resource configuration.
Setting
I have a large Java/Dart project where I need to deploy a WAR file that has both my UI and my backend in separate JARs. I want to cut down on the size of the deployed file, and I want to drop certain folders from the WAR. Based on the plugin documentation, I thought I could simply set excludes in my plugin configuration, and it won't copy over the unnecessary folders. However, it seems the Resources plugin is outright ignoring these, despite, the Maven model package including a setExcludes function.
Current Attempts
So far, I've tried two main approaches. My configuration is as follows:
<configuration>
<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
<resources>
<resource>
<directory>src/main/webapp</directory>
<excludes>
<exclude>web.xml</exclude>
<exclude>appengine-web.xml</exclude>
<exclude>**/web/_el/*</exclude>
<exclude>WEB-INF/pages/frontend/**</exclude>
<exclude>**/_el/js/frontend/**</exclude>
<exclude>**/_el/dart/app/dashboard/lib/**</exclude>
<exclude>**/_el/dart/app/dashboard/.dart_tool/**</exclude>
</excludes>
</resource>
</resources>
</configuration>
I tried to use this config inside the execution element, as well as outside from directly under the plugin element, but both times it was ignored, and everything in the webapp directory was copied over mindlessly.
On a hunch, I did try setting filtering to true, but that just ate up all the memory in my computer, and it didn't even work - what it did process was copied over.
I also tried using the Shade plugin, but gave up on that pretty quickly, as the DontIncludeResourceTransformer only permits suffix-filtering, which is not adequate for my use case.
Question
So what am I doing wrong? Based on the docs, I believe the plugin should respect my excludes list and skip the vast majority of files, but it's evidently not doing that.
You need to use apache **maven war plugin**.
The WAR Plugin is responsible for collecting all artifact dependencies, classes and resources of the web application and packaging them into a web application archive.
It is possible to include or exclude certain files from the WAR file, by using the and configuration parameters. They each take a comma-separated list of Ant file set patterns. You can use wildcards such as ** to indicate multiple directories and * to indicate an optional part of a file or directory name.
Here is an example where we exclude all JAR files from WEB-INF/lib:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
https://maven.apache.org/plugins/maven-war-plugin/examples/including-excluding-files-from-war.html
I'm building (multiple) complex webservice with base XSD types from all kinds of standards (GML, SWE, XLINK, etc). Now, I would like to break up the compilation into more steps, preferrably one for each of the standards I'm using.
Advantages:
1) I can add create tooling libraries that I can re-use in all of my webservices on each of the standards.
2) I can make use of the power of JAXB2 basics plugin, which seems to work very nicely with the maven-jaxb2-plugin (org.jvnet.jaxb2.maven2) and create for instance interface bindings. This in contrast with the jaxws-maven-plugin plugin.
The final step would be using the org.jvnet.jax-ws-commons:maven-jaxb2-plugin to create the actual web service that I can implement in an EJB (or call as a client).
Now, the org.jvnet.jaxb2.maven2:maven-jaxb2-plugin plugin allows me to refer to episodes by means of their maven coordinate, as part of its like this:
<episodes>
<episode>
<groupId>org.example</groupId>
<artifactId>jaxb2-basics-test-episodes-a</artifactId>
</episode>
</episodes>
How can I do this by means of the org.jvnet.jax-ws-commons:maven-jaxb2-plugin? I've searched a lot, and experimented like this:
<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>>maven-jaxb2-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<wsdlDirectory>src/main/resources/</wsdlDirectory>
<wsdlFiles>
<wsdlFile>example.wsdl</wsdlFile>
</wsdlFiles>
<xjcArgs>
<xjcArg>-b</xjcArg>
<xjcArg>../cpt-xsd/target/generated-sources/xjc/META-INF/sun-jaxb.episode</xjcArg>
</xjcArgs>
<verbose>true</verbose>
</configuration>
</plugin>
Which takes the episode file from the target dir of the (compiled) JAXB dependend project. This sometimes even fails in the maven build (why I did not figure out yet).
I've tried to use catalog files to make a mapping but (I think I saw somewhere a catalog mapping that took maven coordinates as destination), but haven't succeeded yet.
Are you aware of the OGC Schemas and Tools Project? (Disclaimer: I'm the author.)
Now, to your question. My guess would be that org.jvnet.jax-ws-commons:maven-jaxb2-plugin does not support the "Maven coordinates" as you call them. This was a feature I've specifically implemented for my org.jvnet.jaxb2.maven2:maven-jaxb2-plugin (disclaimer: I'm the author).
From the other hand, episode file is nothing but a JAXB binding file. So you can simply extract this file from the JAR artifact (for instance using the maven-dependency-plugin) and then include it more or less like you do it already. Just don't point to directories in other modules, this is not reliable.
I'm new to maven, and I want to use maven to generate the java code from a wsdl file (using the wsimport plugin ?), which is in my project (not in a url).
I think the wsdl file should be somewhere in myprojet/src/main/resources, and the generated sources in myproject/target/generatedsources/ws.
If the choice of these places ok ? If so, how can I create the sources from the wsdl to the designated folder using maven ? Can I choose the java package name of the sources ? Should I ? Should I then make a jar file out of the sources ? How can I make sure that the generated sources are accessible for the compilation (in the classpath) ?
thank you.
There are several ways to do this with the wsimport plugin, but most examples would require more knowledge of your pom.xml
Apache CXF is a popular free plugin for this exact purpose
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/myService.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
NOTE: You can definitely make a jar out of the generated sources, but this would be a separate entry inside your POM
check out Apache's Axis2 -- it's designed specifically to help generate code based on an WSDL for web services. Basically it's exactly what you are looking for:
http://axis.apache.org/axis2/java/core/
EDIT: To expand, I typically will run the wsdl2java(.bat or .sh) file and point it to the wsdl (either on the web or local copy) and it generates everything else. It can even package it all into a jar for you (my preferred method because it's "cleaner"). You likely won't have any need to go into the generated code and change anything, you just end up adding that jar to your classpath then import like any other library and use it.
Attempting to modify an existing Java/Tomcat app for deployment on Heroku following their tutorial and running into some issues with AppAssembler not finding the entry class. Running target/bin/webapp (or deploying to Heroku) results in Error: Could not find or load main class org.stopbadware.dsp.Main
Executing java -cp target/classes:target/dependency/* org.stopbadware.dsp.Main runs properly however. Here's the relevant portion of pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<assembleDirectory>target</assembleDirectory>
<programs>
<program>
<mainClass>org.stopbadware.dsp.Main</mainClass>
<name>webapp</name>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
My guess is mvn package is causing AppAssembler to not use the correct classpath, any suggestions?
Your artifact's packaging must be set to jar, otherwise the main class is not found.
<pom>
...
<packaging>jar</packaging>
...
</pom>
The artifact itself is added at the end of the classpath, so nothing other than a JAR file will have any effect.
Try:
mvn clean package jar:jar appassembler:assemble
Was able to solve this by adding "$BASEDIR"/classes to the CLASSPATH line in the generated script. Since the script gets rewritten on each call of mvn package I wrote a short script that calls mvn package and then adds the needed classpath entry.
Obviously a bit of a hack but after a 8+ hours of attempting a more "proper" solution this will have to do for now. Will certainly entertain any more elegant ways of correcting the classpath suggested here.
I was going through that tutorial some time ago and had very similar issue. I came with a bit different approach which works for me very nicely.
First of all, as it was mentioned before, you need to keep your POM's type as jar (<packaging>jar</packaging>) - thanks to that, appassembler plugin will generate a JAR file from your classes and add it to the classpath. So thanks to that your error will go away.
Please note that this tutorial Tomcat is instantiated from application source directory. In many cases that is enough, but please note that using that approach, you will not be able to utilize Servlet #WebServlet annotations as /WEB-INF/classes in sources is empty and Tomcat will not be able to scan your servlet classes. So HelloServlet servlet from that tutorial will not work, unless you add some additional Tomcat initialization (resource configuration) as described here (BTW, you will find more SO questions talking about that resource configuration).
I did a bit different approach:
I run a org.apache.maven.plugins:maven-war-plugin plugin (exploded goal) during package and use that generated directory as my source directory of application. With that approach my web application directory will have /WEB-INF/classes "populated" with classes. That in turn will allow Tomcat to perform scanning job correctly (i.e. Servlet #WebServlet annotations will work).
I also had to change a source of my application in the launcher class:
public static void main(String[] args) throws Exception {
// Web application is generated in directory name as specified in build/finalName
// in maven pom.xml
String webappDirLocation = "target/embeddedTomcatSample/";
Tomcat tomcat = new Tomcat();
// ... remaining code does not change
Changes to POM which I added - included maven-war-plugin just before appassembler plugin:
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
...
Please note that exploded goal is called.
I hope that small change will help you.
One more comment on that tutorial and maven build: note that the tutorial was written to show how simple is to build an application and run it in Heroku. However, that is not the best approach to maven build.
Maven recommendation is that you should adhere to producing one artifact per POM. In your case there are should two artifacts:
Tomcat launcher
Tomcat web application
Both should be build as separate POMs and referenced as modules from your parent POM. If you look at the complexity of that tutorial, it does not make much sense to split that into two modules. But if your applications gets more and more complex (and the launcher gets some additional configurations etc.) it will makes a lot of sense to make that "split". As a matter of fact, there are some "Tomcat launcher" libraries already created so alternatively you could use of one them.
You can set the CLASSPATH_PREFIX environment variable:
export CLASSPATH_PREFIX=target/classes
which will get prepended to the classpath of the generated script.
The first thing is that you are using an old version of appassembler-maven-plugin the current version is 1.3.
What i don't understand why are you defining the
<assembleDirectory>target</assembleDirectory>
folder. There exists a good default value for that. So usually you don't need it. Apart from that you don't need to define an explicit execution which bounds to the package phase, cause the appassembler-maven-plugin is by default bound to the package phase.
Furthermore you can use the useWildcardClassPath configuration option to make your classpath shorter.
<configuration>
<useWildcardClassPath>true</useWildcardClassPath>
<repositoryLayout>flat</repositoryLayout>
...
</configruation>
And that the calling of the generated script shows the error is depending on the thing that the location of the repository where all the dependencies are located in the folder is different than in the generated script defined.
I'm looking to convert a WSDL version 1.1 into a WSDL 2.0 format as part of our maven build process.
I've come across the Woden Converter utility which uses XSL to do this conversion, and would like to use it. However, there seems to be no documentation or examples (that I can find) on how to configure or use the related maven plugin: woden-converter-maven-plugin
Does anyone have experience with this, and could they please share the maven plugin config details?
Justification (for those that require it):
We have a contract-first Web Service and have a recent requirement to expose our WSDL in 2.0 format to one particular client. To save on maintaining two identical WSDLs, we'd like to maintain the 1.1 wsdl and have the build process auto-generate the 2.0 version.
Here are the sources for the plugin. There's not much you can set. Check the fields. You can set those up in the <configuration/> section of your plugin.
Consider this:
<plugin>
<groupId>org.apache.woden</groupId>
<artifactId>woden-converter-maven-plugin</artifactId>
<version>1.0M9</version>
<executions>
<execution>
<id>convert</id>
<goals>
<goal>convert</goal>
</goals>
<configuration>
<wsdl><!-- File or URL of wsdl1.1 document.Also multiple
WSDL files can be specified as a comma separated
list. -->
</wsdl>
<targetNS>
<!-- New target namespace for WSDL2.0 document. -->
</targetNS>
<targetDir>
<!-- Target directory for output, default
location is project build directory. -->
</targetDir>
<sourceDir><!-- Source directory for output. --></sourceDir>
<verbose><!-- Verbose mode --></verbose>
<overwrite><!-- Overwrite existing files. --></overwrite>
</configuration>
</execution>
</executions>
</plugin>