Setting up third party libraries for UIMA AS application - classpath

I have an UIMA AS application that is using third party libraries. I would like to know the following:
1. Where (location) we can add these third libraries such that the deployed application to be aware of them and not throwing "ClassNotFoundException"?
A brute force solution for me, was to add them directly in the UIMA AS "lib/" folder, but this solution was just for testing and is not acceptable in production.
2. How can be set up this third party libraries when generating PEAR file in a such a way that deploying the application will consider them and won't be necessary to manually add them to the classpath?
I'll look forward for your answer. Thank you.

For the first question: my approach was
1. Create a lib folder for the third library
2. create a script that adds to the UIMACLASSPATH the lib folder
#set UIMA_CLASSPATH=%UIMA_CLASSPATH%;../../lib;../../bin
call deployAsyncService.cmd
for the second question:
I use the maven plugin for generating the pear file.
Excerpt from the pom.xml (maven related)
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<!-- Copy the dependencies to the lib folder for the PEAR to
copy -->
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/lib</outputDirectory>
<overWriteSnapshots>true</overWriteSnapshots>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.uima</groupId>
<artifactId>PearPackagingMavenPlugin</artifactId>
<version>2.3.1</version>
<!-- if version is omitted, then -->
<!-- version is inherited from parent's pluginManagement section -->
<!-- otherwise, include a version element here -->
<!-- says to load Maven extensions (such as packaging and type
handlers) from this plugin -->
<extensions>true</extensions>
<executions>
<execution>
<configuration>
<classpath>
<!-- PEAR file component classpath settings -->
$main_root/lib/*.jar
</classpath>
<mainComponentDesc>
<!-- PEAR file main component descriptor -->
</mainComponentDesc>
<componentId>
<!-- PEAR file component ID -->
${project.artifactId}
</componentId>
<datapath>
<!-- PEAR file UIMA datapath settings -->
$main_root/
</datapath>
</configuration>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<!-- Clean the libraries after packaging -->
<execution>
<id>CleanLib</id>
<phase>clean</phase>
<configuration>
<tasks>
<delete quiet="false" failOnError="false">
<fileset dir="${basedir}/lib" includes="**/*.jar" />
</delete>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>

You can extract the compiled classes from your external jars and pack them into your UIMA component jar. As for the PEAR file, you might find that a similar approach works (unpack the pear, add the .class files, repack)

Related

ANTLR4 doesn't work with custom configuration in Maven

I always used succesfully ANTLR4 combined with Maven inside Eclipse.
I just want to change the default directory where I store my grammar, since I do not like the standard path which is src/main/antlr4. The issue of this path is the creation of a new java package, that I really do not want.
So I simply decided to create another directory inside my project named grammar which contains another directory called imports. I did this following simply the website guidelines.
Despite this, when I change the grammar it doesn't generate automatically the new sources, even with the maven commands!
So, this is my configuration file pom.xml:
<!-- ANTLR4 -->
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.5.3</version>
<executions>
<execution>
<configuration>
<goals>
<goal>antlr4</goal>
</goals>
<libDirectory>grammar/imports</libDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
As you can see, the target directory is empty. Before this change, there was a generated-sources directory inside with all the .java files.
So, where is the error?
The correct way is:
<!-- ANTLR4 -->
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.5.3</version>
<executions>
<execution>
<goals>
<goal>antlr4</goal>
</goals>
<configuration>
<libDirectory>grammar/imports</libDirectory>
</configuration>
</execution>
</executions>
</plugin>
The <configuration> tag must be at same level than <goals> tag, inside <execution> tag, according to Maven documentation: https://maven.apache.org/guides/mini/guide-configuring-plugins.html#Using_the_executions_Tag and https://maven.apache.org/guides/mini/guide-default-execution-ids.html
In fact, the documentation in ANTLR4 Maven plugin is wrong:
http://www.antlr.org/api/maven-plugin/latest/examples/libraries.html

Is it possible to use reflections-maven to scan for classes inside jars in web-Inf/lib?

I need to create a list of subclasses for a particular interface during maven build process and then use that at runtime to load those classes. I have added reflections-maven (from google code reflections) in my webapp pom but during maven build, its only including the classes from the web application and not the classes inside the packaged jars that are there in web-inf/lib folder of that application. Below is the straight forward configuration I have used. I looked at the plugin source code and it seems it scans the following: getProject().getBuild().getOutputDirectory().
Is there anyways I can configure the plugin to scan the dependent jar files of the project?
<plugin>
<groupId>org.reflections</groupId>
<artifactId>reflections-maven</artifactId>
<version>0.9.9-RC1</version>
<executions>
<execution>
<goals>
<goal>reflections</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
</plugin>
You can easily run Reflections with any configuration you like, using, for example, gmaven-plugin:
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.3</version>
<dependencies>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.9-RC1</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
new org.reflections.Reflections("f.q.n")
.save("${project.build.outputDirectory}/META-INF/reflections/${project.artifactId}-reflections.xml")
</source>
</configuration>
</execution>
</executions>
</plugin>
So all you need to do is to use the right configuration, maybe in your specific case:
def urls = org.reflections.util.ClasspathHelper.forWebInfLib()
new org.reflections.Reflections(urls)
.save("${project.build.outputDirectory}/META-INF/reflections/${project.artifactId}-reflections.xml")

How can I get tycho materialize-product and archive-product to use a directory prefix for my RCP app archive file

How can I add a prefix directory so when I unpack the zip containing my RCP app I get a directory containing the contents?
When tycho materalizes and archives my rcp app it zips up target/products/my.rcp.app/linux/gtk/x86_64/ contents without a directory prefix.
Current zip contents:
./features
./plugins
...
Desired zip contents:
./myapp/features
./myapp/plugins
...
When a user unpacks the zip, I'd like the app directory to be created. I looked through the tycho docs but neither archive nor materialize seems the right place to configure this. I could always use antrun or assembly plugin to do the work but that doesn't feel like the right maven way to solve the problem.
Please let me know how to add a prefix directory.
The configuration is really a bit messed up and not really documented. Since you (currently) can have multiple product files in one eclipse-repository module, you need to select the product ID for which you want to apply the configuration.
So to set the archive root folder for the product with ID product.id, you need the following configuration:
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>materialize-products</id>
<goals>
<goal>materialize-products</goal>
</goals>
</execution>
<execution>
<id>archive-products</id>
<goals>
<goal>archive-products</goal>
</goals>
</execution>
</executions>
<configuration>
<products>
<product>
<id>product.id</id>
<rootFolder>myapp</rootFolder>
</product>
</products>
</configuration>
</plugin>
</plugins>
</build>
Thanks but I needed to use the rootFolder option to add the extra directory. I tried injecting achivePrefix into the .product file but that didn't work. I finally broken down, grabbed tycho source and worked backwards to find rootFolder. After this journey, I saw it in the doc and grocked the meaning.
Doc: http://wiki.eclipse.org/Tycho/Packaging_Types#Creating_Product_Zip_Files
Related: https://issues.sonatype.org/browse/TYCHO-507
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<products>
<product>
<id>match-product-uid-field-from-foo.product-file</id>
<rootFolder>workbench</rootFolder>
</product>
</products>
</configuration>
<executions>
<execution>
<!-- install the product using the p2 director -->
<id>materialize-products</id>
<goals>
<goal>materialize-products</goal>
</goals>
</execution>
<execution>
<!-- create zip file with the installed product -->
<id>archive-products</id>
<goals>
<goal>archive-products</goal>
</goals>
<configuration>
<formats>
<linux>tar.gz</linux>
<win32>zip</win32>
</formats>
</configuration>
</execution>
</executions>
</plugin>

How to remove directories from final build zip archive using maven 3

When the build is ready i have p2 folder in all build archives for different platforms.As i understand it's imposible to exclude p2 directory from archives on building stage. So I try pack archive myself instead of using archive-products execution.
The problem is if i want to make archives for others platform or architecture I will need to change pom.
Now i have the following build schema:
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>materialize-products</id>
<goals>
<goal>materialize-products</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>pack-zip-files</id>
<phase>package</phase>
<configuration>
<target>
<zip basedir="${project.build.directory}/products/xxx/win32/win32/x86"
destfile="${project.build.directory}/products/xxx-1.0.${BUILD_NUMBER}-win32.win32.x86.zip"
excludes="${exclude_p2}" />
<zip basedir="${project.build.directory}/products/xxx/linux/gtk/x86"
destfile="${project.build.directory}/products/xxx-1.0.${BUILD_NUMBER}-linux.gtk.x86.zip"
excludes="${exclude_p2}" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
The quiestion is how to remove p2 folder from all zip files?
What you are doing now is really the only way to do it. You could change the packaging type to eclipse-application and that directory won't be created, but it is a deprecated packaging type and has a whole slew of problems.
The only way to help with multiple POM support would be to put that POM configuration into a profile and have your projects that build products inherit from it. You can also use the osgi.os osgi.arch properties in place of hard-coding things like win32 and linux.

How to setup bundle development environment (Eclipse Equinox Maven)

I'am trying to setup eclipse environment to develop bundles (With maven-bundle-plugin-bnd)
and run & debug that bundles equinox from eclipse
I created sample bundles with org.apache.felix maven-bundle-plugin and can install and start that bundles from eclipse equinox,
but every time i need to run "install file:C:\path\bundle1.jar","install file:C:\path\bundle2.jar" which causes pain. i searched for run configuration but it only intalls and starts (plugin) projects in workspace not maven projects.
What i have done is create maven project and add dependencies(bundle1,bundle2 etc..) and added maven-dependency-plugin to copy all depended bundles in one folder (another problem is equinox use "_" delimeter to determine version of bundles but maven uses "-" as delimeter) if i do not strip version in standalone equinox application i need to give version of bundle in config.ini file but i dont want that, is this proper way to solve this problem?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${bundleDirectory}</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<stripVersion>true</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
To sum up , i have bundles in folder, which is created with org.apache.felix maven-bundle-plugin , how can i run and debug them from eclipse?
I wouldn't say this is a "proper" solution, but it may work for you.
The antrun plugin can be used to modify the dependencies to replace the final hyphen with an underscore, so the dependency plugin doesn't need to strip the version.
My regex is rusty, but from a little testing the following configuration appears to apply the required name change to the files in the bundleDependency directory.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${bundleDirectory}</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<phase>package</phase>
<configuration>
<tasks>
<!-- move within same directory is preferred method for a rename-->
<move todir="${bundleDirectory}">
<fileset dir="${bundleDirectory}"/>
<mapper type="regexp" from="([a-zA-Z0-9\.-]+)(-)([0-9\.]+.jar)"
to="\1_\3"/>
</move>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.6.5</version>
</dependency>
</dependencies>
</plugin>
I wrote a tool called auto-builder (http://code.google.com/p/auto-builder). It introspects PDE-based projects and generates Ant build files; it supports transitive closure over dependencies and all that jazz.
I posted a write-up: http://empty-set.net/?p=9. I wrote it because the Maven tools I played with, when integrated with PDE, didn’t “just work.” Basically, I wanted to do coding in PDE and have a Hudson-based CI without any fuss in between.
Generating Ant files is nice because it gives you all the benefits of a declarative build tool, but it leaves you with a procedural description of what it is doing.
I am looking for more PDE-based projects to test it on. There are a couple RFC-0112 Bundle repositories around, and I have some code for downloading dependencies. If anyone is interested, then I could integrate dependencies download with auto-builder.