Bug #1593
closedSaxon .NET throws NoClassDefFoundError when bytecode generation is enabled
100%
Description
When a Saxon from .NET application is run from Visual Studio 2010 using following code:
Processor processor = new Processor();
XsltCompiler xsltCompiler = processor.NewXsltCompiler();
using (StringReader sr = new StringReader(xslt)) {
XsltExecutable xsltExecutable = xsltCompiler.Compile(sr);
The last line throws NoClassDefFoundError, the stack trace of the error is as follows:
at IKVM.NativeCode.java.lang.ClassLoader.defineClass1(ClassLoader thisClassLoader, String name, Byte[] b, Int32 off, Int32 len, Object pd, String source)
at java.lang.ClassLoader.defineClass1(String , Byte[] , Int32 , Int32 , ProtectionDomain , String )
at java.lang.ClassLoader.defineClass(String name, Byte[] b, Int32 off, Int32 len, ProtectionDomain protectionDomain)
at java.lang.ClassLoader.defineClass(String name, Byte[] b, Int32 off, Int32 len)
at com.saxonica.bytecode.util.CompilerService$1.findClass(String )
at java.lang.ClassLoader.loadClass(String name, Boolean resolve)
at java.lang.ClassLoader.loadClass(String name)
at com.saxonica.bytecode.util.CompilerService.makeClass(ClassWriter writer, String className)
at com.saxonica.bytecode.BlockCompiler.generateBlockIterator(CompilerService , Expression , Expression[] )
at com.saxonica.bytecode.BlockCompiler.compileToIterator(CompilerService compiler, Expression expression)
at com.saxonica.bytecode.util.CompilerService.compileToIterator(Expression expr)
at com.saxonica.bytecode.util.CompilerService.compileToByteCode(Expression expr, String objectName, Int32 evaluationModes)
at com.saxonica.bytecode.LetExpressionCompiler.compileCommonExpr(CompilerService compiler, Expression exp, Int32 evaluationMode, Int32 refCount)
at com.saxonica.bytecode.ApplyTemplatesCompiler.compileParameterSet(CompilerService compiler, ExpressionCompiler ec, WithParam[] params)
at com.saxonica.bytecode.CallTemplateCompiler.compileToPush(CompilerService compiler, Expression expression)
at com.saxonica.bytecode.util.CompilerService.compileToPush(Expression expr)
at com.saxonica.bytecode.ElementCreatorCompiler.compileToPush(CompilerService compiler, Expression expression)
at com.saxonica.bytecode.util.CompilerService.compileToPush(Expression expr)
at com.saxonica.bytecode.util.CompilerService.compileToByteCode(Expression expr, String objectName, Int32 evaluationModes)
at com.saxonica.expr.ee.OptimizerEE.compileToByteCode(Expression expr, String objectName, Int32 evaluationMethods)
at net.sf.saxon.style.XSLTemplate.optimize(Declaration declaration)
at net.sf.saxon.style.PrincipalStylesheetModule.compileStylesheet()
at net.sf.saxon.PreparedStylesheet.setStylesheetDocument(DocumentImpl doc)
at net.sf.saxon.PreparedStylesheet.prepare(Source styleSource)
at net.sf.saxon.TransformerFactoryImpl.newTemplates(Source source, CompilerInfo info)
at Saxon.Api.XsltCompiler.Compile(TextReader input)
Files
Updated by O'Neil Delpratt over 12 years ago
- Status changed from New to Resolved
- % Done changed from 0 to 50
Class loader issue where it cannot find the base class: com.saxonica.bytecode.GeneratedCode
Solution:
In the makeClass
method of the CompilerService
class we can explicitly pass the class loader of com.saxonica.bytecode.GeneratedCode (i.e. the parent class loader) of the class loader to load the generated class. That is a more general solution as it does not require the system class loader (i.e. the main executable, in .NET) to be able to reference the base class.
As a workaround we can add the following C# code in the main executable:
GC.KeepAlive(typeof(com.saxonica.bytecode.GeneratedCode));
Updated by O'Neil Delpratt over 12 years ago
- Status changed from Resolved to In Progress
Updated by O'Neil Delpratt over 12 years ago
Updated by O'Neil Delpratt over 12 years ago
- % Done changed from 50 to 90
Bug fix has been committed to subversion.
In the getClassLoaderForGeneratedClass
method of the DotNetPlatform class we have changed the logic of fetching the parent ClassLoader from the CompilerService class first, which at this point should not be null.
The bug issue is marked as resolved, but I note the following observation in Visual Studio 2010, when bytecode generation is enabled. Given that we have a try-catch statement for XPathException in the C# code, we are still getting the following exception thrown
'net.sf.saxon.trans.XPathException was unhandled by user code'@. Checks have been done to make sure we are using the same classloader as a result of the call to the @getClassLoaderForGeneratedClass
method.
Updated by Michael Kay about 12 years ago
Just to clarify, the current status (in 9.4 SVN) is that bytecode generation is working under .NET 4.0, except when dynamic errors occur, in which case we are not catching the exception.
Updated by O'Neil Delpratt about 12 years ago
- Status changed from In Progress to Resolved
- % Done changed from 90 to 100
Bug fixed and committed to subversion, which will be available in the next maintenance release. We are now catching dynamic errors
Updated by O'Neil Delpratt about 12 years ago
- Status changed from Resolved to Closed
- Fixed in version set to 9.4.0.6
Please register to edit this issue