xjc generated code references OverrideAnnotationOf annotation from sun internal package - jaxb

I'm trying to generate Java classes from a set of XML schemas. The following binding file is used to handle mixed content in the schemas:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.1"
xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc">
<jaxb:globalBindings generateMixedExtensions="true"/>
</jaxb:bindings>
The code generation works fine but one of the generated classes has an #OverrideAnnotationOf from the com.sun.xml.internal.bind.annotation package. This package is included in rt.jar but the regular java compiler can't find it (and probably shouldn't find it because it is sun internal).
Is there a way to deal with the mixed content and not have the OverrideAnnotationOf from a sun internal package in my generated code?

In Java 6 and up, oracle moved the JAXB implementation embedded within the JRE to a different package to prevent potential collisions with the external JAXB reference implementation.
So the class OverrideAnnotationOf got moved from package com.sun.xml.bind.annotation to package com.sun.xml.internal.bind.annotation.
The embedded xjc, however, still generates java files that are annotated with com.sun.xml.bind.annotation.OverrideAnnotationOf(!)
Therefore, the JAXB implementation shipped with Java 7 will not understand its own output generated with generateMixedExtensions="true". Even if you use the -XDignore.symbol.file option.

Related

Java 8 Javadoc vs. XJC Warnings & Errors

How do I use xjc to generate Java code from xsd files which have 0 Javadoc Warnings and Errors at build time when using Java 8 and not changing which Doclint being used?
I'm using an Apache-Ant build.xml file to build the codebase.
I can't.
According to JAXB, those build problems are not blockers, "since workaround is to pass -Xdoclint:none to javadoc executable". =(
Yes, it is possible to hand-edit the generated Java files to get 0 Warnings and 0 Errors, but my main goal is to generate Java files that do not require hand edits (or custom plugins) under any and all circumstances.

Xamarin/MonoTouch: Unable to compile in "Link SDK only" mode due to missing symbols

I am trying to compile my iOS application using MonoTouch in Link SDK only mode. It compiles completely fine if I turn off linking entirely but it also produces a colossal binary which is not suitable for release mode.
Unfortunately, one of the libraries that I need somehow invokes Expression.Visit and I can't figure out how to instruct the linker to not strip it out. This results in this compilation error:
Error MT2002: Failed to resolve "System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor::Visit(System.Linq.Expressions.Expression)" reference from "System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" (MT2002) (MyApp)
As per the documentation on custom linking, I have set up a linker file to try to stop this happening:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.ExpressionVisitor">
<method signature="System.Linq.Expressions.Expression Visit(System.Linq.Expressions.Expression)" />
</type>
</assembly>
</linker>
Unfortunately, that doesn't have any effect - the error just happens as before.
The documentation mentions a preserve="fields" parameter I can supply to <type>, so I tried that:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.ExpressionVisitor" preserve="methods" />
</assembly>
</linker>
That didn't work either.
I then introduced an XML syntax error into the file and the build failed saying it couldn't parse the linker file so I at least know that the file is being read.
But then I tried introducing errors into the assembly name:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="NonexistentAssembly">
</assembly>
</linker>
That caused an error, complaining that the assembly couldn't be resolved.
I then tried to mangle the type name:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="NonExistentType" preserve="methods" />
</assembly>
</linker>
Now, that just started showing the same "unable to resolve expressionvisitor::visit" error I was seeing before. It seems that type names are not checked.
Also, neither are signature names as this also presented the same compilation error.
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.ExpressionVisitor">
<method signature="jg98j23890rj2390erk90fk3ew!]['##'#'[" />
</type>
</assembly>
</linker>
So it seems that so long as you specify the assembly name and have a valid XML structure, the linker file does not cause any exceptions to be thrown. The documentation for the linker file though is not especially verbose for such a complex topic and includes numerous syntax errors, i.e.:
<type fullname="Foo" preserve="fields" />
<method name=".ctor" />
</type>
Also, it doesn't give a technical description of the linker file format so it's entirely possible that my definition is totally wrong.
I have also tried just skipping the linking of System.Core entirely with --linkskip=System.Core but this has no effect. I have tried this flag both with and without --xml.
In the MvvmCross project, I tried specifying a new class to call the Visit method in the same style as the LinkerPleaseInclude.cs file that gets added to every iOS project by the MvvmCross NuGet package:
[Preserve]
public class PleaseIncludeVisitor : ExpressionVisitor
{
public PleaseIncludeVisitor()
{
this.Visit(null);
}
}
Unfortunately, this also had no effect.
I am currently using Mono 3.2.6 ((no/9b58377) and Xamarin.iOS v7.0.7.2.
The main issue is that it is not possible to do code generation at runtime on iOS.
That means that a large part of System.Linq.Expressions would, normally, be impossible to provide under normal circumstances (just like System.Refection.Emit can't be provided).
To workaround this Xamarin.iOS has been providing an alternative implementation (that can interpret the most common expressions).
However the current code is not 100% API compatible with the .NET framework (that's fixed but not yet released). E.g.
System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor::Visit(System.Linq.Expressions.Expression)
The above returns void in the current Xamarin.iOS (7.0.x) releases. That why the linker complains (it's not a bug) as it cannot find this member reference (and if it can't find it it cannot recreate the smaller, linked, assemblies). It is not possible to preserve a member that does not exist (which is why your attempts to use XML files or attributes won't help).
The current workaround is to identify which of your assemblies is using this API and rebuild it (from source) to use the existing System.Core.dll that is shipped with Xamarin.iOS.
Notes
I can't figure out how to instruct the linker to not strip it out.
The linker does not try to strip it out it tries to keep it in (i.e. it must load the reference to be able to save it back). However it cannot find that member in System.Core.dll making it impossible to provide a valid linked version of the assemblies.
<method signature="System.Linq.Expressions.Expression Visit(System.Linq.Expressions.Expression)" />
That's asking to preserve something that does not exist. It will be ignored, i.e. when the void-returning version is found it will not match the XML description.

How to work-a-round with JSF annotation processing bug on Jetty?

There's a bug in JSF loading mechanism for managed beans annotated with annotation #ManagedBean. The mechanism is not activated when running the app via mvn jetty:run. The bug is reported here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=288243
This is a very nasty thing, because jetty:run have great advantages when debugging:
it is fast
it works directly with the jsf files from workspace, without need to use FileSync plugin
However, not supporting the annotation would require downgrading to XML configuration.
Is there any work-a-round for this bug?
source : the link you provided in your question , read Tomaz Lipinsi comments
Hi, I've found a easy workaround for this problem. Actually I don't
use Jetty but Tomcat and Sysdeo Tomcat Launcher but it behaves the
same. JSF2 is looking for annotated classes in two places:
- WEB-INF/classes - so if the app is not packaged into .war, this directory does not exist
- classpath jars (WEB-INF/lib) - similar as above I've tried to override default com.sun.faces.spi.AnnotationProvider to my own so I
could provide him a list of my classes (see JavaDoc for this class).
While I was trying to do this then I hit upon an idea that I could
just simply put my compilled classes in WEB-INF/classes dir. Adding
this to pom.xml solved the problem:
src/main/webapp/WEB-INF/classes
The drawback is that now I have compiled classes in source
dir but the most important is that it works.
Suggest you to read all the comments there.
For avoid a mix between src and classes, you can set in your maven's POM some like this:
<build>
<finalName>my-project</finalName>
<directory>target</directory>
<outputDirectory>${basedir}/target/main/webapp/WEB-INF/classes</outputDirectory>
....
</build>
And in the configuration of jetty's maven-plugin you can try this:
Edit: Jetty's version used is 6.1.26, if tag 'resources' doesn't work try 'resourcesAsCSV' instead
<configuration>
...
<webAppConfig>
<defaultsDescriptor>${basedir}/src/main/webapp/WEB-NF/webdefault.xml</defaultsDescriptor>
<baseResource implementation="org.mortbay.resource.ResourceCollection">
<resources>${basedir}/target/main/webapp,${basedir}/src/main/webapp</resources>
</baseResource>
</webAppConfig>
...
</configuration>
**Note: webdefault.xml is for setting an init-param needed for unblock files while jetty is running, the param is:
<init-param>
<param-name>useFileMappedBuffer</param-name>
<param-value>false</param-value>
</init-param>

complex jaxb scenario on generation of java objects

I have a project that does JAXB generation with framework.xsd. This generates a jar with the xsd and the jaxb objects and other classes around that stuff.
Then another group(two different groups) will be extending framework.xsd and subxmling using the schema extends stuff to extend objects in framework.xsd. They also want to generate jaxb objects BUT they want their SomeClass.java to obviously extend my Framework.java and don't want to end up with a whole new heirarchy.
Is this even possible?
How to do something like this? as the solution would need to
tell the jaxb compiler that the namespace yy is already generated so do not generate
tell the jaxb compiler that it needs to refer to the classes in the package zzzzzz or to look at the xjb file from the framework jar file or something.
Is this possible?
thanks,
Dean
You want to use an episode file : http://weblogs.java.net/blog/kohsuke/archive/2006/09/separate_compil.html when generating JAXB classes for your first schema.
$ xjc -episode framework.episode framework.xsd
Then the other group that consumes your framework.jar should:
1) import your schema in their own schema e.g.:
<xsd:import namespace="http://www.myorg.com/framework" schemaLocation="framework.xsd"/>
2) generate their JAXB classes
$ xjc extend.xsd -b framework.episode
(they'll need a copy of your xsd and episode file at xjc time, as well as the framework.jar in the classpath)
Note that according to the blog post above, you can also place the framework.episode file inside your jar (e.g. /META-INF/sun-jaxb.episode for JAXB RI at least - other JAXB impl may have other ways of accomplishing the same thing), so that the -b framework.episode option can be omitted. I personally find it a bit impractical, you still need the XSD anyway.

JAXB : use local schemaLocation to generate Java classes

I am trying to generate Java classes from a XSD schema using the xjc command that comes with JAXB.
My schema looks like:
<xs:schema xmlns="..."
xmlns:ext="http://schemas.myco.com/ext" ... >
<xs:import namespace="http://schemas.myco.com/ext"
schemaLocation="http://myco.com/schemas/ext.xsd"/>
...
The problem is that the schemaLocation URI does not exist and I can not modify the XSD file. That is why the generation process fails with errors such as "src-resolve: Cannot resolve the name 'ext:Resource_Type' to a(n) 'type definition' component".
Is there any way to force JAXB to use a local copy of ext.xsd file during the process without modifying the original XSD file ?
Two possible solutions:
JAXB Episode File:
http://weblogs.java.net/blog/2006/09/05/separate-compilation-jaxb-ri-21
or
XML Catalogs (search Google)

Resources