Nuxeo automation and a custom enricher - nuxeo

I'm trying to learn how to develop my own enricher (I believe I do understand the basic, in terms of how enrichers relate to automation chains and so on). However, I'm having problems:
I can use existing enrichers with, for example,
Document.FetchByProperty and everything will work
But once I include my own custom enricher, I get the error (link below)
I couldn't figure out what I'm doing wrong, so I've took existing custom enricher from Nuxeo sample project, and got the same error
Any help is welcome!
Log link: https://answers.nuxeo.com/api/files/2b14d403-aa8a-4ac3-81ca-c9ee13623c2a
I've also asked the same question here:
https://answers.nuxeo.com/general/q/af5a6369c91942b5a81bf61549b467f2/Automation-and-a-custom-enricher

Make sure that you are compiling the enricher code with the same version of Nuxeo libraries as is the version of the target platform.
For example sample project is using the latest version (currently 11.1-SNAPSHOT) and the result code will not be compatible with Nuxeo platform 9.2. Especially abstract methods can have problems.
So there should be this section in pom.xml with <version>9.2</version> in your case:
<parent>
<groupId>org.nuxeo</groupId>
<artifactId>nuxeo-addons-parent</artifactId>
<version>9.2</version>
</parent>
The reason why the java.lang.AbstractMethodError is thrown here is in JsonGenerator. Nuxeo 9.2 uses org.codehaus.jackson.JsonGenerator while newer Nuxe versions use com.fasterxml.jackson.core.JsonGenerator.
Then this method signature (in 9.2):
public void write(org.codehaus.jackson.JsonGenerator jsonGenerator, DocumentModel documentModel) throws IOException;
... is not compatible with this (in 10.3 for example):
public void write(com.fasterxml.jackson.core.JsonGenerator json, DocumentModel document) throws IOException;
And Java is then not able to find correct write() method implementation and throws AbstractMethodError.

Related

How to use JAXB 2.2.11 in osgi (Liferay DXP)

I’m trying to use JAXB 2.2.11 in an osgi environment (Liferay DXP). I am having issues creating a JAXBContext. Based on some other sources found while researching like this and this, I have determined that in an osgi container I need to provide the correct classloader for JAXB to instantiate the context. So I have code like this:
ClassLoader cl package.with.jaxb.objects.ObjectFactory.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance("package.with.jaxb.objects ", cl);
This code causes a null pointer exception with the following stack trace:
Caused by: java.lang.NullPointerException
at javax.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:129)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:201)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:146)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:371)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:446)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:409)
Looking at the source for ContextFinder I can see that context must be null on line 129:
throw handleClassCastException(context.getClass(), JAXBContext.class);
I thought perhaps the problem was that my module has a dependency on jaxb-api 2.2.11 but the jaxb-impl classes are provided by rt.jar at runtime and are probably newer than 2.2.11 because Liferay DXP runs on JDK 1.8. To get around this issue, I have tried including jaxb-impl.jar 2.2.11 as a dependency in my osgi module, thinking then the jaxb-api & jaxb-impl versions would match. After that, trying to create a JAXBContent using the same code as above results in the following error:
ClassCastException: attempting to cast jar:file:/C:/Program%20Files/Java/jdk1.8.0_144/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class to bundleresource://623.fwk616113009:13/javax/xml/bind/JAXBContext.class. Please make sure that you are specifying the proper ClassLoader.
By the looks of this message, the JAXBContext that is getting instantiated is from the version of JAXBContext that is loaded via rt.jar. This is very confusing to me because I would expect the version of JAXBContext loaded by my module’s classloader to be used since I’ve included jaxb-impl.jar in my module and I’ve specified my module’s classloader is the one to be used in my call to JAXBContext.newInstance. Can anyone shed some light on how I can get jaxb 2.2.11 to work in an osgi container?
*Please note that I can’t upgrade the version of jaxb-api used by my module because the JAXB code is actually in a 3rd party jar that requires jaxb 2.2.11 (I have just eliminated the 3rd party jar from the equation for now by writing some test JAXB code).
After extensive research I found the following solution. Since it seemed like passing the bundle class loader as suggested by the accepted answer in this post had to be correct, I followed the path of figuring out why I was getting a NullPointerException when I tried that. After carefully looking over the source code for jaxb-api to follow the stack trace of the NullPointerException, I could see that the jaxb-api code does things like
classLoader.loadClass("com.sun.xml.internal.bind.v2.ContextFactory")
where classLoader is my bundle's class loader (since that's what I passed in) and ContextFactory is actually a class in jaxb-impl which is loaded by the bootstrap class loader. This is where the problem lies because my
bundle's classloader isn't going to be able to see classes loaded by the bootstrap class loader. This threw me for a while because I'm not used to how class loaders work in osgi. I incorrectly was thinking the classes loaded by the bootstrap class loader would be visible because I'm used to web app class loading where there is delegation. In osgi class loaders
are completely isolated from each other, things are only visible if they are exported. To get around the issue I found some helpful posts talking about similiar issues. It turns out there is a concept
called boot delegation in osgi where you can specify a list of classes/packages to always be loaded via the bootstrap classloader. So the end result is two steps:
1) Switch the thread's class loader to your bundle class loader before calling the code to get the JAXBContext:
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
try {
// ObjectFactory here is in the same package as my classes to be marshalled
ClassLoader objectFactoryClassLoader = ObjectFactory.class.getClassLoader();
Thread.currentThread().setContextClassLoader(objectFactoryClassLoader);
// JAXB code goes here
} finally {
Thread.currentThread().setContextClassLoader(currentClassLoader);
}
2) Specify packages to be loaded using the boot delegation mechanism. This list needs to include the transitive dependencies of the classes you need loaded. In my case, I'm using Liferay so the list
is specific to Liferay and it goes in portal-ext.properties configuration file. Luckily I found this post where someone had done most of the work for me:
module.framework.properties.org.osgi.framework.bootdelegation=\
__redirected,\
com.liferay.aspectj,\
com.liferay.aspectj.*,\
com.liferay.portal.servlet.delegate,\
com.liferay.portal.servlet.delegate*,\
com.sun.ccpp,\
com.sun.ccpp.*,\
com.sun.crypto.*,\
com.sun.image.*,\
com.sun.jmx.*,\
com.sun.jna,\
com.sun.jndi.*,\
com.sun.mail.*,\
com.sun.management.*,\
com.sun.media.*,\
com.sun.msv.*,\
com.sun.org.*,\
com.sun.syndication,\
com.sun.tools.*,\
com.sun.xml.*,\
com.yourkit.*,\
org.eclipse.persistence.internal.jaxb,\
org.eclipse.persistence.internal.jaxb.*,\
javax.xml.*,\
sun.*
Helpful links:
Why can't JAXB find my jaxb.index when running inside Apache Felix?
What is the difference between bootdelegation and DynamicImport-Package in osgi
https://web.liferay.com/web/user.26526/blog/-/blogs/liferay-dxp-and-weblogic-
https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/bundle-classloading-flow
http://apache-felix.18485.x6.nabble.com/Classloading-for-JAXB-td4834670.html
Here is the workaround that worked for me using JDK 11, Liferay DXP/7.2, OSGI, with a sample Jax-RS web service created from Dev Studio. The error I was getting was as follows when trying to access the web service:
JAXBException occurred : Implementation of JAXB-API has not been found
on module path or classpath..
com.sun.xml.internal.bind.v2.ContextFactory cannot be found by
org.apache.aries.jax.rs.whiteboard_1.0.4.
What worked for me was to define the context factory at the system level to override the predefined context factory. Add the following system variable to your system
javax.xml.bind.JAXBContextFactory=com.sun.xml.bind.v2.ContextFactory
For example you can add this in your setenv.sh/bat file in Tomcat, or in eclipse you can access your server Launch Configuration, Arguments tab, under VM arguments
-Djavax.xml.bind.JAXBContextFactory=com.sun.xml.bind.v2.ContextFactory
This worked without adding any extra libraries since Liferay already has those libraries included.
How does this work? Refer to the javadoc for JaxBContext and read the Discovery of JAXB implementation Section. Using the /META-INF/services/javax.xml.bind.JAXBContext file did not work for me.
I hope this helps someone.
One final note for DXP users, if you get a permission denied on your service then you need to read about Service Access Policies
The best place to see how it should be done is Apache Karaf. It doesn't install any JAXB-API bundle - instead it uses org.apache.servicemix.specs.jaxb-api-2.2-2.7.0.jar inside lib/endorsed directory.
This way you won't use JAXB-API provided by rt.jar.
For implementation - it's best to use ServiceMix version of JAXB bundles:
org.apache.servicemix.bundles:org.apache.servicemix.bundles.jaxb-impl:2.2.11_1
org.apache.servicemix.bundles:org.apache.servicemix.bundles.jaxb-xjc:2.2.11_1

IAppBuilder could not be found

I read the previous posts - Tried a few things.
Here is the issue
A simple console OWIN self host app - Not much in there
public void Configuration(IAppBuilder appBuilder)
does not compile.
1. If I say using Microsoft.Owin and using Owin, then I get an error the using directive for owin already appeared. I can't figure out why.
2. If I do using Microsoft.Owin but modify the use as Owin.IAppBuilder
then the compiler says it can't find owin.IAppBuilder.
Yes I tried reinstalling Microsoft.Owin
and Owin (3 times)
I checked the project reference 4.5.1
Here is an issue to consider.
If your using statements are insider a namespace declaration
And your name space starts with Microsoft (for whatever reasons)
Then using Owin ==> looks at Microsoft.Owin
The solution is to use using global::Owin;

Error serializing with ServiceStack JSON on MonoTouch

I am experimenting with ServiceStack's JSON engine. I grabbed the MonoTouch binary build, v2.20. Works fine from simulator, but from the iOS device (iPad2, iOS5) I get an exception thrown by the type initializer for JsonWriter (and not much other than that). I am using MonoTouch 5, MonoDevelop 2.8.1, and targeting iOS 5. I have disabled library linking because I am getting an error when enabled.
I created a sample and uploaded to https://github.com/t9mike/ServiceStack-JSON1.
I'm trying to determine whether the issue is my compilation options, Service Stack, or MonoTouch. Thanks in advance.
A quick partial answer that might help:
I have disabled library linking because I am getting an error when enabled.
The current (5.0) managed linker can eliminate some unused (from a static analysis point of view) code from your application. This generally occurs when using Link all option, i.e. where user code gets processed by the linker.
One alternative is using the Link SDK assemblies only that won't touch the user code (only the code shipped with MonoTouch itself will be processed by the linker).
Another alternative is adding [Preserve] attributes on your code to ensure the serializer requirements are still met after the linker has processed your code. More information about the linker and [Preserve] attributes can be found here.
The next (5.2) release of MonoTouch will include a bit more sophisticated step in the linker to ensure the basic XML serialization and DataContract requirements are not broken. Not sure if this will solve this specific case (ServiceStack JSON) but I'll have a look into it.
As for the rest of your question I'll try to build this myself and duplicate your issue.
I ended up grabbing the ServiceStack.Text sources from GitHub, version 3.0.3. I created a new MonoTouch library project. I had to tweak ServiceStack.Text/JsConfig.cs slightly to conditionalize away the System.Drawing.Color bits. I'll send a patch and MT csproj to the authors.
After using this new assembly, my sample MT app ran fine on the device. I have updated my sample at https://github.com/t9mike/ServiceStack-JSON1 with the new ServiceStack.Text dll.

Nuget Moq 4.0.10827 and InternalsVisibleTo (Again)

I have been trying to get Moq (or rather Castle.Core) to create proxies for my internal types.
The following (when added to my project under test), allows things to work:
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
However this (more secure version) does not:
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=002400000480000094000000060200000024000052534131000400000100010077f5e87030dadccce6902c6adab7a987bd69cb5819991531f560785eacfc89b6fcddf6bb2a00743a7194e454c0273447fc6eec36474ba8e5a3823147d214298e4f9a631b1afee1a51ffeae4672d498f14b000e3d321453cdd8ac064de7e1cf4d222b7e81f54d4fd46725370d702a05b48738cc29d09228f1aa722ae1a9ca02fb")]
Note: the public key here differs to that documented here, I re-checked the public key of the Castle.Core.dll that ships with the current Nuget version of Moq.
Do I still have the wrong key?
[EDIT]
I have noticed the full Moq download from the official site (rather than Nuget) contains a NET40-RequiresCastle folder with a smaller dll, which implies that the Castle.Core code has been included in the default Moq.dll I guess.
I was looking at the Castle.Core.dll they provide for Silverlight and assuming they'd have used the same version throughout?
I know this is old, but for anyone who stumbles across this, I was having a versioning issue with Pex and Moq at one point, and wound up finding the most direct and useful approach to be the Strong Name Tool. That is, I found opened a Visual Studio command prompt and used "sn -Tp ThirdPartyAssembly.dll" to query it for the key directly. This proved a lot more efficient than perusing the internet looking for different, documented public keys to try out.

Xerces error: org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl

I'm developing a web application using JSF 2.0, NetBeans 6.9.1, GlassFish Server 3.1, mojarra 2.0.3, and JasperReports 3.7.6. Included in my project library is the jar file "xerces-2.8.0.jar". This file was imported as part of the JasperReports jar file library. Whenever I try to deploy, run, or debug my project through NetBeans, I receive this error:
java.lang.Exception: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: com.sun.faces.config.ConfigurationException: CONFIGURATION FAILED! DTD factory class org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl does not extend from DTDDVFactory.
After any change in my project my build fails, and I receive the above error, when I try to deploy, run, or debug it. I have to restart the server and run/debug a second time. I've searched the internet and cannot find a solution to this problem. I've looked at the jar file in question, and and DTDDVFactoryImpl does indeed extend from DTDDVFactory - I don't know why I'm receiving this error. While I can eventually get my project running, it would be much nicer if I wasn't receiving this error.
Can anyone please tell me how I can fix this? Do I need to remove this file from my project library? Do I need to update this file with a newer version/older version?
If you provide your own xerces.jar, you have to do that through the Endorsed Standards Override Mechanism (java -Djava.endorsed.dirs=/path/to/xerces.jar), you are not allowed to just add it on the classpath (and will sooner or later run into trouble if you do). Let me explain.
JAXP is the Java API for XML Processing. The creation of JAXP objects (like parsers, XSLT transfomers, DOM Documents) is done through the factory/factory-method pattern so you can plugin a new JAXP implementation (it has to be newer than the one provided in your JRE). Xerces provides (part of) a JAXP implementation and contains endorsed standards (an endorsed standard is a Java API defined through a standards process other than the Java Community Process, see the Endorsed Standards Override Mechanism). You'll run in all kinds of troubles if you don't use the ESOM.
I got this error when using Selenium with Glassfish. I got around it by copying XML jars (xerces-*, xalan-*, xml-apis*, serialize*) from selenium/libs/ to $AS_HOME/lib/endorsed (for Glassfish 2) or to $AS_HOME/glassfish/lib/endorsed for Glassfish 4.

Resources