NoSuchMethodError when running UIMA Ruta script from UIMAFIT SimplePipeline - uima

I am trying to run an existing UIMA Ruta analysis engine from a UIMAFIT simple pipeline using the following code:
File specFile = new File("MyEngine.xml");
XMLInputSource in = new XMLInputSource(specFile);
ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in);
AnalysisEngineDescription aed = (AnalysisEngineDescription) specifier;
builder.add(aed); // Builder is an aggregateBuilder
Upon running it, it resolves imports from the engine's main script (the Cleartk Stanford tools) and then quits with the following exception:
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.uima.ruta.type.RutaBasic.setLowMemoryProfile(Z)V
at org.apache.uima.ruta.RutaStream.initalizeBasics(RutaStream.java:173)
at org.apache.uima.ruta.engine.RutaEngine.initializeStream(RutaEngine.java:575)
at org.apache.uima.ruta.engine.RutaEngine.process(RutaEngine.java:432)
at org.apache.uima.analysis_component.JCasAnnotator_ImplBase.process(JCasAnnotator_ImplBase.java:48)
at org.apache.uima.analysis_engine.impl.PrimitiveAnalysisEngine_impl.callAnalysisComponentProcess(PrimitiveAnalysisEngine_impl.java:378)
at org.apache.uima.analysis_engine.impl.PrimitiveAnalysisEngine_impl.processAndOutputNewCASes(PrimitiveAnalysisEngine_impl.java:298)
at org.apache.uima.analysis_engine.asb.impl.ASB_impl$AggregateCasIterator.processUntilNextOutputCas(ASB_impl.java:568)
at org.apache.uima.analysis_engine.asb.impl.ASB_impl$AggregateCasIterator.<init>(ASB_impl.java:410)
at org.apache.uima.analysis_engine.asb.impl.ASB_impl.process(ASB_impl.java:343)
at org.apache.uima.analysis_engine.impl.AggregateAnalysisEngine_impl.processAndOutputNewCASes(AggregateAnalysisEngine_impl.java:265)
at org.apache.uima.analysis_engine.asb.impl.ASB_impl$AggregateCasIterator.processUntilNextOutputCas(ASB_impl.java:568)
at org.apache.uima.analysis_engine.asb.impl.ASB_impl$AggregateCasIterator.<init>(ASB_impl.java:410)
at org.apache.uima.analysis_engine.asb.impl.ASB_impl.process(ASB_impl.java:343)
at org.apache.uima.analysis_engine.impl.AggregateAnalysisEngine_impl.processAndOutputNewCASes(AggregateAnalysisEngine_impl.java:265)
at org.apache.uima.analysis_engine.impl.AnalysisEngineImplBase.process(AnalysisEngineImplBase.java:267)
at org.uimafit.pipeline.SimplePipeline.runPipeline(SimplePipeline.java:80)
at org.myproject.workflow.ParagraphAnnotationPipeline.main(ParagraphAnnotationPipeline.java:107)
The engine was created using a pre-release of Ruta 2.2.0 and the pipeline runs in UIMA 2.5.0 using UIMAFIT 2.0.0 and Ruta-core 2.1.0 imported using maven.
Thanks for any help!

This problem is most likely caused by the fact that the JCas classes are overwritten. UIMA Ruta provides a few JCas classes of the types defined for seeding, inference and additional analysis engines. One of them (at least, but most important) contains additional methods for storing information about annotations and more: RutaBasic. These JCas classes must not be overwritten.
There is a mention in the README for users that apply JCasGenPomFriendly:
If you use the uimaFIT JCasGenPomFriendly in Maven and want to use UIMA Ruta
as a standalone annotator you have to exclude the generated UIMA Ruta basic
type files from the build, e.g., by adding:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<excludes>
<exclude>org/apache/uima/ruta/type/*.java</exclude>
</excludes>
</configuration>
</plugin>
Can you please check if you generated RutaBasic and if the class contains for example the method setLowMemoryProfile.

Related

AEM How to update POI version in OSGi Bundle Wrapper For The Apache POI Library?

In AEM, there's a bundle named "OSGi Bundle Wrapper For The Apache POI Library".
I want to update POI version of that bundle to use POI 5.2.3 with AEM 6.3.
Is there's any way to easily update POI version in this bundle?
Thanks.
Apache POI provides a module to build an all-in-one OSGi bundle, see https://github.com/apache/poi/tree/trunk/osgi
It can either replace the OOB POI bundle, or you can build your own one on top of it, having the POI code in the internal classpath.
In your custom core bundle pom, you may specify embed dependency for the poi version you require. So that your bundle will refer to the poi version from embedded jar and not provided by AEM container.
Have you tried using the tag of maven-bundle-plugin -
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version></version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${bundle.symbolicName}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Bundle-Name>${bundle.name}</Bundle-Name>
<Export-Package>${bundle.namespace}</Export-Package>
<Bundle-Activator>Activator.class</Bundle-Activator>
<Embed-Dependency>*;scope=!provided|test;groupId=!org.mybundle.test</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
<Import-Package>*;resolution:=optional</Import-Package>
</instructions>
</configuration>
</plugin>
You can either include all the dependencies or you can configure to not to include specific ones. The scope attribute lets you configure which dependency jars you want to include based on their include scope. You should not include the dependencies which are only needed for compile and for test.
https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/how-to-embed-dependent-jar/m-p/225793

Fix com.day.cq.commons,version=[5.7,6) can't be resolved in OSGi Bundles in AEM 6.2

when you working with AEM 6.2 you might have came across below error,
com.day.cq.commons,version=[5.7,6)-->can't be resolved
This happened in AEM 6.2 Versions
I answered below.
Another Solution for this issue is :
copy and paste “cq-commons-5.9.26.jar” file in /.m2/repository/com/day/cq/cq-commons/5.9.26
and update pom dependency to below :
<dependency>
<groupId>com.day.cq</groupId>
<artifactId>cq-commons</artifactId>
<version>5.9.26</version>
<scope>provided</scope>
</dependency>
Solution:
Add below dependency in AEM Core Project pom.xml file
<dependency>
<groupId>com.day.cq</groupId>
<artifactId>cq-commons</artifactId>
<version>5.7.4</version>
</dependency>
Add Import Package in Core pom.xml
<Import-Package>
com.day.cq.commons;version="[5.7.0,7.0)",
</Import-Package>
build maven and deploy the project in AEM. build should be in active state.
references:
The instruction is a list of packages that are required by the bundle's contained packages. The default for this header is "*", resulting in importing all referred packages.
This header rarely has to be explicitly specified. However, in certain cases when there is an unwanted import, such an import can be removed by using a negation package pattern. The package patterns work in the same way as for , which means they are ordered.
For example, if you wanted to import all packages except org.foo.impl you would specify "!org.foo.impl,*"

p2-maven-plugin -- bundle conflicts with other existing bundle

I’m starting to use the p2-maven-plugin in order to integrate non-OSGi JARs into our project in a (hopefully) convenient manner.
I have an artifact which I want to OSGi-ify, called com.thirdparty.artifact. I’m current using p2-maven-plugin’s standard configuration, and I list my artifact in the pom.xml like so:
<artifact><id>com.thirdparty:artifact:1.2.3</id></artifact>
This artifact has a transitive dependency called com.thirdparty:library:2.5, which exports a package com.thirdparty.library which is in turn imported by com.thirdparty:artifact. When I run mvn p2:site, I get a P2 site which contains com.thirdparty:artifact:1.2.3 and com.thirdparty:library:2.5 -- all fine so far.
Now, things are turning messy. My existing target platform already contains an artifact called com.othervendor:library (different vendor, it’s there and I cannot change that), which also exports the very same package com.thirdparty.library (but an entirely different version).
At runtime, the OSGi/Eclipse black magic (which I’ll probably never fully understand) tries to resolve com.thirdparty:artifact’s dependency on the package com.thirdparty.library using the com.othervendor:library and not my provided com.thirdparty:library:2.5 -- and I’m obviously in trouble. Here’s a visualization of my situation:
Being absolutely no OSGi rocket scientist, my first idea was to inspect the MANIFEST.MF in com.thirdparty:artifact. Beside others, this shows the following:
Import-Package: com.thirdparty.library
So, this obviously just tells com.thirdparty:artifact to import this package from some bundle, and OSGi/Eclipse thinks “okay, com.othervendor:library is more adequate than com.thirdparty:library”.
There seem to be two methods of narrowing down the dependencies to actually use. However: I’m not sure (a) how to integrate them into my p2-maven-plugin workflow, and (b) I do not understand why p2-maven-plugin does not automatically require the concrete package version in the Import-Package directive (this information is after all already specified in the source pom.xml).
Probably I’m not seeing the forest for the trees here. So any general advice beside my questions above is very welcome!
[edit] Here’s my pom.xml (the concrete library which I’m about to OSGi-ify is Selenium):
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>com.example.p2dependencies</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.reficio</groupId>
<artifactId>p2-maven-plugin</artifactId>
<version>1.2.0</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<artifacts>
<artifact><id>org.seleniumhq.selenium:selenium-java:3.4.0</id></artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
[edit2] Problem seems to be solved, it seems, the issue was an additional package which was only exported by com.othervendor:library.

saveToCassandra with spark-cassandra connector throws java.lang.ClassCastException

When trying to save data to Cassandra(in Scala), I get the following exception:
java.lang.ClassCastException:
com.datastax.driver.core.DefaultResultSetFuture cannot be cast to
com.google.common.util.concurrent.ListenableFuture
Please note that I do not get this error every time, but it comes up randomly once in a while which makes it more dangerous in production.
I am using YARN and I have shaded com.google.** to avoid the Guava symbol clash.
Here's the code snippet:
rdd.saveToCassandra(keyspace,"movie_attributes", SomeColumns("movie_id","movie_title","genre"))
Any help would be much appreciated.
UPDATE
Adding details from the pom file as requested:
<dependency>
<groupId>com.datastax.spark</groupId>
<artifactId>spark-cassandra-connector_2.10</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>com.datastax.spark</groupId>
<artifactId>spark-cassandra-connector-java_2.10</artifactId>
<version>1.5.0</version>
</dependency>
**Shading guava**
<relocation> <!-- Conflicts between Cassandra Java driver and YARN -->
<pattern>com.google</pattern>
<shadedPattern>oryx.com.google</shadedPattern>
<includes>
<include>com.google.common.**</include>
</includes>
</relocation>
Spark version: 1.5.2
Cassandra version: 2.2.3
Almost everyone who works on C* and Spark has seen these type of errors. The root cause is explained here.
C* driver depends on a relatively new version of guava while Spark depends on an older guava. To solve this before connector 1.6.2, you need to explicitly embed C* driver and guava with your application.
Since 1.6.2 and 2.0.0-M3, by default connector ships with the correct C* driver and guava shaded. So you should be OK with just connector artifact included in your project.
Things get tricky if your Spark application uses other libraries that depend on C* driver. Then you will have to manually include un-shaded version of connector, correct C* driver and shaded guava and deploy a fat jar. You essentially make your own connector package. In this case, you can't use --package to launch Spark cluster anymore.
tl;dr
use connector 1.6.2/2.0.0-M3 or above. 99% you should be OK.

Replace class files before maven assembly

I'm facing a very unique situation and need some advice:
I'm working on a project which depends on an other project from my same company and now I need to apply some modifications to the dependency.
The problem which I have is that the source code from the dependency has been lost, so the only thing I have is a maven dependency in the repository, with the corresponding jar file.
On top of that, some of the classes in the Jar file where created using JiBX parser, mapping some XSD files which I neither have, and the resulting classes are synthetic and I found no decompiler able to handle them properly.
The only good thing of all of that is that the class which I need to change can be properly decompiled, so went for the following:
I decompiled the whole jar file and ended up with some classes (the
JiBx ones) with empty or wrongly implemented methods.
I commented out the body of the wrong methods to have stub objects, applied the required changes to the right classes and recompiled.
I took the old Jar file, opened it and manually replaced the old class with the new one.
And the resulting Jar worked as expected.
Now my question is: Can I do all of that using Maven?
The idea would be to put the JiBX class files as resources, and keep the stub equivalents as source files and then let maven:
Compile everything as usual, putting all the compiled class files
into target folder
Remove stub class files from target folder and replace them with the old precompiled class files
package the jar.
Which approach would you recommend?
UPDATE
I give some more details about the dependency project structure:
All classes are inside the same package:
my.project.domain.JiBX__c_GeneratedObfuscatedClass1.java
my.project.domain.JiBX__c_GeneratedObfuscatedClass2.java
my.project.domain.JiBX__c_GeneratedObfuscatedClass3.java
my.project.domain.CustomizableClass1.java
my.project.domain.CustomizableClass2.java
my.project.domain.CustomizableClass3.java
JiBX classes are not imported properly as dependency and if I try to put any of the CustmizableClasses into the project source and let the JiBX ones be in a dependency, the compiler reports missing methods.
I also tried using the Shade Plugin as suggested, but since I need to include the JiBX classes into my source path, I will end up having to include into package JiBX classes from jar dependency and compiled CustomizableClasses, but skipping CustomizableClasses from jar dep and compiled JiBX classes.
I looks like it can work, but I admit that I still didn't find the way of doing it.
Any clues will be very welcomed.
UPDATE 2 (RESOLUTION)
I explain here how I finally managed this using the shade plugin as suggested, just in case someone else needs to do the same:
I finally created a project with the decompiled classes inside the same package, and left the methods which didn't want to be decompiled commented out.
In the pom.xml I added the following:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>${project.groupId}:${project.artifactId}</include>
<include>TheDamnedProject:WithoutSources</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>TheDamnedProject:WithoutSources</artifact>
<includes>
<!-- These classes will be taken directly from dependency JAR -->
<include>my/package/ClassWhichCouldNotBeDecompiled1.class</include>
<include>my/package/ClassWhichCouldNotBeDecompiled2.class</include>
<include>my/package/ClassWhichCouldNotBeDecompiled3.class</include>
<include>my/package/ClassWhichCouldNotBeDecompiled4.class</include>
</includes>
</filter>
<filter>
<artifact>${project.groupId}:${project.artifactId}</artifact>
<excludes>
<!-- These classes will be overridden by the ones inside the JAR -->
<exclude>my/package/ClassWhichCouldNotBeDecompiled1.class</exclude>
<exclude>my/package/ClassWhichCouldNotBeDecompiled2.class</exclude>
<exclude>my/package/ClassWhichCouldNotBeDecompiled3.class</exclude>
<exclude>my/package/ClassWhichCouldNotBeDecompiled4.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
thanks!
Carles
Here's how I would do that:
Create a new Maven project for this Jar file, with packaging type jar
Include the original Jar file as a dependency
Add the one decompiled .java file in the src folder
This should get you to a point where the .java file can be compiled, since the other classes from the jar file are available.
You now have two Jar files: one original, and one that should just contain the single recompiled and changed class.
Adding both to your application class path might work, but will depend on the order on the classpath.
If you want to end up with one jar file, I recommend to take a look at the Maven Shade Plugin (http://maven.apache.org/plugins/maven-shade-plugin/), which will allow you to create a new Jar file with contents from multiple sources. It will allow you to filter what goes into the new Jar file.
The Maven Shade plugin allows you to specify which classes from each artifact are included. It uses wildcards and include/exclude tags for this, as described here: http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html
Once that Jar file is created, I would release it using the Maven Release plugin, and then include that artifact downstream. This will allow you to only update the patched Jar when it is really required, it probably doesn't have to be on every build. But that depends on your usage pattern.
For the version number of the new Jar file, I recommend to use a variation of the original one. Use the same groupId and artifactId, then modify the version number. If the original has 1.0.2, your new, patched file should be released as 1.0.2-1, to indicate that it's based on the 1.0.2 sources. If you need to make an additional change, release that as 1.0.2-2 and so on. This will make it easy to understand which version your patches are based on, and the incrementing patch number will give you a means to distinguis the releases.