Using JAXBContext.newInstance("com.jaxbgen") to bind classes in this package.
And then use this context to create mashaller.
It's so strange that one entity class xxx in this package could not mashaller, and throw JAXBException nor any of its super class is known to this context.
And the other works well.
I try to use JAXBContext.newInstance(xxx.class) to initial the context, it works well.
But I need to use package name to mashaller all classed in this package.
Could anyone help me on it?
When the package name is used to create a JAXBContext the JAXB impl does one of the following:
Looks for a class called ObjectFactory and then transitively pulls in all reference ed classes.
Looks for a text file called jaxb.index which contains a carriage return separated list of short class names (not package qualified). These classes and all referenced classes are the processed.
Related
I defined objects with XSD model and I used Jaxb to create corresponding classes, to be able to load XML files on instance of classes and to generate XML files from instance of classes.
My elements defined on the XSD model are complex with several hierarchical level, using list, ID and IDREF.
One command of my program is to duplicate elements.
I can't use the clone method cause classes of element are generated by JAXB.
So i have tried to do deep copy with BeanUtils.cloneBean, next with SerializationUtils.clone from Apache but both methods don't work correctly with all my objects because of their complexity.
I found a solution that work, using JAXB to create a clone unmarshalling my element :
public ObjectXML duplicate(ObjectXML objectXML) throws JAXBException {
JAXBContext sourceJaxbContext = JAXBContext.newInstance(objectXML.getClass());
JAXBContext targetJaxbContext = JAXBContext.newInstance(objectXML.getClass());
Unmarshaller unmarshaller = targetJaxbContext.createUnmarshaller();
ObjectXML objectCopy = (ObjectXML) unmarshaller.unmarshal(new JAXBSource(sourceJaxbContext, objectXML));
return objectCopy;
}
ObjectXML is my parent class from all elements generated by JAXB. All elements inherit directly or indirectly from this class.
This method work fine except with IDREF attributes that link to another object : JAXB don't know the element that have the corresponding ID when I unmarshall an individual object, so it assign null to the attribute.
Have someone a solution to keep IDREF on the copy when linked object are not supplied to the unmarshal of JAXB?
Thank you for advance.
Few hints.
Try the copyable plugin from JAXB2-Basics. This plugin generates deep reflection-free copying methods which handle JAXB structures very well, and you can also specify your own copying strategy. Disclaimer: I'm the author.
Implement and register your own IDResolver, see this blog post. This would allow you to plug your own ID resolution strategy.
I am using spring ws to implement my web service.
I am getting the following error in web service
"There's no ObjectFactory with an #XmlElementDecl for the element test"
test is having a #XmlElementRef.
While creating the jaxb context I have used ContextPath set to the package name.
I have done the following things:
Used xjc parse to convert from WSDL to pojos.
I had multiple WSDL's so the ObjectFactory was getting overwritten. So I just renamed the objectfactory prefix with WSDL. A.wsdl will have AObjectFactory etc. So I dont have any ObjectFactory class.
I think when looking for #XmlElementDecl it looks for "ObjectFactory" class and then it cant find it, bcoz if I rename my AObjectFactory to ObjectFactory this works.
My question is:
Can #XmlElementRef not refer to renamed object factory created by me?
Can #XmlElementRef be avoided somehow?
Can we have multiple ObjectFactories?
Also how does #XmlElementRef and #XmlElementDecl works if we do not create ObjectFactories at all.
Any help will be great.
While creating the jaxb context I have used ContextPath set to the
package name.
When you create a JAXBContext by context path, the JAXB implementation is going to look for a class called ObjectFactory that is annotated with #XmlRegistry.
I had multiple WSDL's so the ObjectFactory was getting overwritten.
Generally there should be one ObjectFactory per namespace/package. If the ObjectFactory was getting overwriiten perhaps you were trying to force everything to the same package name.
So I just renamed the objectfactory prefix with WSDL. A.wsdl will have
AObjectFactory etc. So I dont have any ObjectFactory class.
When the class annotated with #XmlRegistry is called something other than ObjectFactory you need to either:
Include a text file called jaxb.index in the same package as your domain model that contains the short name of all your classes in that package annotated with #XmlRegistry.
Bootstrap the JAXBContext of the generated classes annotated with #XmlRegistry.
I am trying to use org.xhtmlrenderer:core-renderer:R8pre2 in a groovy script, but I get a Linkage error:
Caught: java.lang.LinkageError: loader constraint violation in interface
itable initialization: when resolving method
"org.apache.xerces.dom.NodeImpl.getOwnerDocument()Lorg/w3c/dom/Document;"
the class loader (instance of org/codehaus/groovy/tools/RootLoader) of the
current class, org/apache/xerces/dom/NodeImpl, and the class loader (instance of
<bootloader>) for interface org/w3c/dom/Node have different Class objects for
the type getOwnerDocument used in the signature
I've already googled a lot and found a lot of answer like these:
Dealing with "Xerces hell" in Java/Maven?
XercesImpl in conflict with JavaSE 6's internal xerces implementation. Both are needed... what can be done?
So, one solution could be to use javas endorsed mechanism to resolve the conflict, but I would like to make my script independent from such a "workaround". The script should run out of the box.
Next thing I was giving a try was to exclude the right dependency like this
#Grapes([
#Grab('org.xhtmlrenderer:core-renderer:R8pre2'),
#GrabExclude('xml-apis:xml-apis')
])
but didn't succeed...
Any ideas?
PS: here is the script which creates the error:
#Grapes([
#Grab('org.xhtmlrenderer:core-renderer:R8pre2'),
])
import org.w3c.dom.Document
import javax.xml.parsers.DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory
def dbf = DocumentBuilderFactory.newInstance()
DocumentBuilder builder = dbf.newDocumentBuilder()
Document doc = builder.parse(new ByteArrayInputStream("<html></html>".getBytes()))
Thanx to #dmahapatro, I checked my configuration and found that I dropped some jars in {usrhome}/.groovy a long time ago. Removed these and now everything work like a charm...
We have classes of this form classA version1, classA version2, classA version3 .. etc. This is same class that has been modified. Each "modification" creates a new version of a class. Each object has a version attribute which refers to the version of the class from which it was derived. eg ObjectA.version =1 # means it was derived from ClassA version1
Here is my problem. During object de-serializing, i would like to use the specific version of the class that was used to used to make the object. For example, if i am de-serializing object ObjectA with version=3 then ClassA version 3 should be used. Source code for all the different variations of the classes is stored.
This looks getting the object first the get the class. Any idea on how to approach this?
You have three options:
Custom serialisation/deserialisation - you can put version information and class information first.
Create a "union class" which has all of the members of all of the class versions, then use that to create an instance of the appropriate class.
Refactor to a common base class, and have each "version" inherit from that class.
I would recommend option 3, because then your versions can co-exist cleanly.
How can we add some common constraints (i.e. maxLength, nullable) to a property of a Groovy class? I know we can do it at Grails domain class, but is it possible if that is a Groovy class (I use it as a DTO class for my Grails project)?
Thank you so much!
You can add constraints to command classes. If a command class is in the same .groovy file as a controller (in Groovy you can have more than one public class in each .groovy file), you don't need to do anything special for Grails to recongise it as a command class.
However, if your command class is somewhere else (e.g. under src/groovy), you need to annotate it with #Validateable and add the package name to the grails.validateable.packages parameter in Config.groovy. Here's an example of a command that's not in the same file as a controller
pacakge com.example.command
#Validateable
class Person {
Integer age
String name
static constraints = {
name(blank: false)
age(size 0..100)
}
}
Add the following to Config.groovy
grails.validateable.packages = ['com.example.command']
Command classes have a validate() method added by Grails. After this method is called, any errors will be available in the errors property (as per domain classes).
Using a grails Command Object is probably your best bet. It has constraints and validation, but no database backing. It's normally a value object that controllers use, but you could instantiate one outside of a controller without any problems.
Not sure if this is relevant to your use (I am not familiar with DTOs), but in the current version (2.3.8), you can also add Grails constraints to an abstract class, and they will be inherited by the domains that extend it. Your IDE might not like it though ;)