What's a good way to generate XML from vanilla Adobe CQ5? - java

My current implementation generates XML using JSPs, but the number of different record types I'm working with has grown and the number of JSP templates has become unwieldy to maintain.
So I coded up a solution using javax.xml.bind but quickly found that the code would compile but not run in OSGi. Long story short, there is a natively compiled dependency -- com.sun.* -- that is not included in the Felix boot classpath by default. Including this dependency is a matter of modifying sling.properties to include com.sun.* in the org.osgi.framework.bootdelegation config line. However, I'm working in a large corporate production environment so the thought of managing an extra configuration piece is not ideal.
So, the meat of my question: is there a better way to generate custom XML programmatically in Adobe CQ? Is there a different JAXB impl in the stack that I should be using, instead of javax.xml.bind? Is there another XML marshalling API that is more CQ/Felix friendly?

I've not got any concrete documentation on this yet, but it's possible to include com.sun.* without changing the Sling boot delegation.
I've done it in this pom.xml for a demo project using CXF in CQ5 as an OSGi service. It's either the <dependency> or the <Import-Package> in the maven-bundle-plugin.
The whole project is available on GitHub at https://github.com/antonyh/cq5-cxf - it builds, installs, and works without changes to boot delegation on CQ5.4 / CQ5.5.

CQ5.5 osgi bundles include org.apache.cocoon.cocoon-xml which exports packages:
org.apache.cocoon.xml.dom,version=2.0.0
org.apache.cocoon.xml.sax,version=2.0.0
Which are available for use in other osgi bundles or component jsp files.

For "vanilla" XML you can simply add a .xml extension to your content URL and an XML representation of the content will be output. This can be fetched by HTTP.

Related

Java EE, how to ignore annotations in certain JAR or package

I'm using a JAR library, which contains #WebService annotated classes and other Java EE annotations. The problem is, Weblogic 12c automatically discovers these annotations and provides the services. This is not the intention, rather I would like to use the JAR only as an utility library inside other Java EE project, and ignore all Java EE related configuration from Weblogic point-of-view considering this library.
Basically the library in question is another Java EE project ruthlessly bundled inside a JAR, but modifying the library is out of question, thus I need to ignore all the Java EE stuff in that library.
So, how do I instruct weblogic to ignore all the Java EE related stuff in this specific JAR archive (or alternatively all the classes under certain package specifier) from automatic discovery and configuration?
One solution that comes in my mind is metadata-complete=true in web.xml which seems to ignore those annotations. However, I'm not sure if it ignores annotations only in JAR libraries or annotations in the project itself too.
You could read about the solution of metadata-complete here. This solution actually was created in order to improve the deployment performance on large scale Java EE projects.
You should try to set metadata-complete=true in the web.xml file of the library project and then create a new jar based on this change. This is against your will to refactor the library code, nevertheless it is a minor change which would not take lot of your time.
However, I'm not sure if it ignores annotations only in JAR libraries or annotations in the project itself too.
You are right. If you make this change in your project's web.xlm file then you will affect your annotations also.

Swagger does not recognize #Api annotation if used in ear module but swagger deployed in war

We are using Wildlfy 10 and Swagger 1.5.12 (Swagger 2.0 Spec)
In our application we are deploying the contract and implementation of our webservice in our ear to ensure being able to exchange the implementation on this level.
The war exposing our webservice is packaged in the same ear and has access to all its modules.
The swagger definition is placed in the war file. While the webservice endpoints are working as intended the swagger.json only contains the general information but does not contain the Api documentation.
After debugging a while i came to the following result:
The classes are discovered by the Scanner using reflections.getTypesAnnotatedWith(Api.class)
trying to generate the config afterwards they are using cls.getAnnotation(annotationClass) and alternatively cls.getAnnotations() and annotation = metaAnnotation.annotationType().getAnnotation(annotationClass); both return null
After debugging further i narrowed it down to the fact, that the Annotation attached to the class is loaded by the ear-classloader while swagger is using the war-classloader (as it is placed in the war).
This is conform to the Wildlfy Documentation as war-modules use a different classloader.
Other questions were answered with
I think you'll end up with other issues with the multiple classloader issue
source
and
To be honest it should be also said that when you load the same class in more than a ClassLoader it's quite easy getting other side effects, like static state duplication and so on.
That's why I think the developers using swagger in exotic scenarios - like build systems integration - should be warned about the fact that the library uses reflection for code analysis, hence the classloader matters.
source
Deploying the contract and ejb module in our war solved it, but unfortunately is no valid solution in our architecture.
Questions:
Is there a (non hacky) way to load the swagger-annotations-jar in the ear module with the same classloader in bot the war and ear modules?
Is it possible to solve this by tweaking the swagger configuration? (adjusting the implementation to not use reflection is only the last resort)
Can this be seen as a bug of swagger?

WildFly RestEasy Version confusion

I want to build a REST API using RestEasy. The generated file should be deployed in a WildFly application server.
I face the issue described in the following SO-question:
AsynchronousDispatcher error
The marked solution tells me, to set the dependency to "provided". Which as far as I understand means, that the library is not included in my war file but taken directly from the app-server...
Isn't that just wrong?
My idea would be to build a self-containing war file which contains all the needed libraries in the version I need.
When provided from the app-server I do get the currently available version from there. I have not really a clue about the version... when someone has the idea to update the RestEasy library on the server, it might break my app.
I'm not sure whether I missed something or did something completely wrong?
One of the big advantages to Java EE is developing towards the API and not having to worry about the implementation. Java EE containers provide the API's and implementations for the API's. If you include implementation dependencies one of two things is likely to happen.
You're dependencies will be ignored making it pointless to include them in your deployment.
You'll get conflicts between the dependencies you included vs what the server is expecting. This could be things like:
ClassCastException because it's finding two of the same class on the class path.
MethodNotFoundException because there is a version mismatch
Various other issues with conflcts
Developing towards the API instead of the implementation also allows you to easily switch between Java EE compliant containers with no to minimal changes to your deployment. The API's are generally backwards compatible as well making version upgrades not as big of an issue.
If you want to use a fat WAR (including implementations) instead of a skinny WAR (not including the implementations) then a servlet container is probably a better solution. WildFly does have a servlet only download. I'd encourage you though to trust container to do the right thing with the implementation dependencies :). Usually the only time there is an issue with upgrading is if you're upgrading Java EE versions. Even then it's usually pretty safe.

How use two verions of itext jar files in pom.xml?

In my project i have dependencies displaytag and birt-runtime. And here display tag needs itext-2.0.1.jar and birt-runtime needs itext-2.1.7.jar so how can i declare this in my pom.xml to use itext-2.0.1.jar only by displaytag and use itext-2.1.7.jar only by birt-runtime. could some one let me know how to achieve this?
Thanks in advance.
In normal java application this is not possible, because in the application itext 2.1 and 2.0 will share the same classloader.
But normally, java-apis take care about backward-compatibility, so it should be possible to include only 2.1.
If not, you need multiple classloaders and then it will become complicated.
Existing solutions:
You could try to add an OSGi container to your application and run
both dependencies as a separate osgi-bundle.
If you run a jboss
application server, you could create one module with displaytag and
another one with birt-runtime.
DIY:
I've never done this but you could try to create to manage your own classloaders in your application and load the dependent jars into each own classloader. This article seems to cover the topic.
Short answer: you can't.
Long answer: Maven is a build tool and has no effect on runtime class loading in your application. Normally what it generates is one (or more) artifact(s), tipically jar or war files that may or may not contain your project's dependencies (depending on your POM files).
What you want to achieve is done at runtime by class loaders but under normal circumstances you don't want to tamper with class loading.
What you could do is:
Exclude unnecessary transitive dependencies of a dependency in your pom by defining exclusions, this way only one version of itext would be used. Of course, this only works if your dependencies don't rely on the internals of itext and their public API's are compatible but this might be the cleanest and easiest solution.
Use a framework/container that has stronger control over class loading, such as an OSGi container. These container provide bundles (somewhat equivalent to artifacts) with "private" class loaders enabling your application having multiple versions of the same library loaded that don't interfere with each other. This solution, however, has other disadvantages and I would only recommend this if you're already familiar with OSGi.

XML serialization for Groovy classes

For an application build on Spring MVC + Groovy + Google App Engine i need simple XML serializer/marchaller.
I'v tried:
XStream - it doesn't work on Google App Engine, because it uses restricted (at GAE) classes
Jaxb2 - it doesn't work with Groovy classes, because groovy class have additional (hidden) fields (like metaClass, etc)
XmlBeans as I understand can be used only for deserializing from XML to Java Beans
Castor seems to be big overhead (i don't need any XMLSchema and so on)
I want to just dump class to the corresponding XML, and i want to configure tag names using some simple config (java annotations, for ex), without XMLSchema/DTD
So, requirements is:
usable at Google App Engine
no XMLSchema/DTD
simple configuration
fast
it's enough only object->xml
maven2 support
groovy support (or manually configured list of used fields)
(optional) spring integration
Can anyone recommend me an good tool for this?
I don't know if there is a lib which fits your requirements, but you could take a look into that list: http://karussell.wordpress.com/2009/09/03/xml-serializers-for-java/
e.g. the simple lib is a good candidate

Categories