I have looked at below mentioned question:
Java JAXB how to create POJO classes
Java JAXB xml pojo classes
Here is what I want to do.
I want to use JAXB and create POJO Java classes at runtime. If I change my XML in future, I don't need to make change POJO Java class structure manually. I need to only restart whole Java Application and it will generate all classes at runtime without user input
FYI :-
using XJC is not helpful as i can not merge it into application.
I have already automated whole business logic which is not affected by XML file.
Here are some maven modules which you may find helpful
jaxb2-maven-plugin
Mojo's JAXB-2 Maven plugin is used to create an object graph from XSDs based on the JAXB 2.1 implementation and to generate XSDs from JAXB annotated Java classes.
maven-jaxb2-plugin
This Maven plugin wraps and enhances the JAXB Schema Compiler (XJC) and allows compiling XML Schemas (as well as WSDL, DTDs, RELAX NG) into Java classes in Maven builds.
jaxb2-maven-plugin
This plugin uses the Java API for XML Binding (JAXB), version 2+, to generate Java classes from XML Schemas (and optionally binding files) and to create XML Schemas from annotated Java classes
Related
I am using JAXB-2 Maven Plugin to generate java classes starting from some xsd files. My configurations is the following. I have three schema files without target namespace A included by B included by C and then I have two others schemas D and E with a provided namespace, both of them including C.
Is it possible to use bindings or different executions (with episodes) to have each schema producing classes in a different packages? Something like:
A schema (no namespace) -> com.packageA
B schema (no namespace) -> com.packageB
C schema (no namespace) -> com.packageC
D schema (namespace X) -> com.packageD
E schema (namespace X) -> com.packageE
of course without classes duplication? Or the best I can have is to have two packages, one for classes belonging to XSDs files with the empty namespace and one for the two XSDs files with the namespace X? Could you please provide an example of pom.xml file to achieve that?
Thanks
And how can
Disclaimer: I'm the author of maven-jaxb2-plugin so this answer is about that plugin.
This is called "separate schema compilation". This can be achieved using episodes, see the explanation in the maven-jaxb2-plugin docs.
In short:
Create one Maven project per logical schema. I normally have one project per distinct namespace.
If schema B uses schema A, include artifact of schema A as dependency of B.
maven-jaxb2-plugin will use dependencies as episodes by default.
In some cases some restover classes are still generated for included episodes. They should not be, I believe it is a bug in XJC. In those cases, add clean-up task.
Be ready to face a number of weird problems as XJC is a tricky tool.
Here's a project which compiles a huge set of schemas in this fashion. The result is some 100+ artifacts with dependencies closely resembling dependencies of schemas.
One problem which I see is that you have schemas A, B and C having the same (empty) namespace, mapping to different packages. This may not work well with JAXB (see also "chameleon namespaces").
We can see many tutorials that shows how to produce soap webservice using xsd in spring-boot. Is it possible to create soap webservice without xsd and from plain Java code using spring-boot-webservice module like we do using #webservice annotation in jax-ws
Guides like this start with an xsd file because they use xjc to create java classes from the XSD definition. xjc creates classes with JaxB annotations (javax.xml.bind.annotation). JaxB is an xml binding specification that has been part of the JDK since 1.6, and it requires that all types from the xsd exist as java classes.
I suggest that you do a tutorial that starts with an xsd an take a look at the auto generated classes. There is nothing to prevent you from writing you own classes instead of generating them from a wsdl, and if you don't refer to external schemas I prefer to do the code only approach (I hate xml configuration).
If you look at the tutorial, the gradle task "getJaxb" will create .java files into "build/generated-sources" compile them and copy them into "build/classes" if you copy the *.java files into "src/main/java" (keep the package structure) and delete delete/disable the "genJaxb" task in gradle, and delete your build folder, everything still works (it actually works better since you normally have red lines in your IDE because the XML beans don't exist until you run the generator the first time).
Now all you need to do is master the JaxB annotations, so you can write your own beans.
I use package-info.java to specify #XmlAccessorType(XmlAccessType.NONE) and some xml java adapters using #XmlJavaTypeAdapters. Model objects (with JAXB annotations) are placed in separate maven module shared by other modules. The configuration in package-info.java is not discovered if model objects are in separate maven module. If I move for testing purposes model objects to same maven module everything is OK. I think separate maven module can be considered equivalent to 3rd party lib from JAXBContext point of view. I use JDK1.7 JAXB reference implementation. Any ideas how configuration may differ?
I also encounter this problem, in my case qualified/unqualified property from package-info.java was ignored. I managed to find two way to workaround this:
like Pavla wrote, copy all JAXB classes with package-info.java locally
include module as a dependency with compile scope (which gives similar result that classes are in module. In my case I created separate jar lib with JAXB classes)
I also spotted that it do not work only in case of creating WebServices (creating object and sending to WS works fine in different modules).
I am using Jbossas7.1.1 and cxf 2.4.6. In the time of registering service Jboss created wsdl from JAXB (in my case path /opt/jboss/jboss-as-7.1.1.Final/standalone/data/wsdl/module.war/SubmitMessage.wsdl). In local setting file is generated properly.
Any ideas why creating WS behaves like this?
I hit this issue recently and the actual problem (with Java 8, i.e. no Java modules involved) was that I had on the classpath two *.jar files which both contained the same package - in one JAR, there was package-info.class with JAXB annotations and in the other one, there wasn't.
In that case, I guess that if package-info.class file is discovered depends on the classpath ordering (which is very brittle and only semi-deterministic).
I have an XSD file with many ComplexType defined in it. I'm using XJC to generate java classes from the XSD file. It will generate classes for all the CompleXType node defined in the schema file. Is there any way I can use a filter in xjc command so that I can get classes of the specified ComplexType only, Instead of generating classes for the whole XSD file?
You can use binding files to somewhat achieve that:
Use <jaxb:schemaBindings map="false" ... /> to disable generation for the whole namespace/schema
Use <jaxb:class ref="com.acme.foo.Ignore"/> to map "unwanted" classes to some (existing) com.acme.foo.Ignore class.
I have xsd which contain the following: type="EAIschema:eCodes" where eCodes is another schema. When I compile it using xjc it returns:
"Cannot resolve the name 'EAIschema:eCodes' to a(n) 'type definition' component"
I want to know how to solve this problem
I'm not 100% sure about the error message, but it looks to me as if the JAXB classes for the other XSD were missing. If your XSD uses data structures of the other XSD then your JAXB classes will need those JAXB classes.
Solution: generate/ add the JAXB classes for the other XSD to your classpath.
If those classes are in a separate JAR, make sure it contains an episode file.
When the XJC tool is converting the XML schema(s) to Java classes it will automatically pull in imported/included schemas based on their system id. It those schemas are not available at the specified system id (or its not specified) then you could use an XML catalog.
For More Information
http://blog.bdoughan.com/2011/10/jaxb-xjc-imported-schemas-and-xml.html