Project

Profile

Help

Bug #1593

closed

Saxon .NET throws NoClassDefFoundError when bytecode generation is enabled

Added by O'Neil Delpratt almost 12 years ago. Updated over 11 years ago.

Status:
Closed
Priority:
High
Category:
Byte code generation
Sprint/Milestone:
-
Start date:
2012-07-20
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:

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

Actions #1

Updated by O'Neil Delpratt over 11 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));

Actions #2

Updated by O'Neil Delpratt over 11 years ago

  • Status changed from Resolved to In Progress
Actions #4

Updated by O'Neil Delpratt over 11 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.

Actions #5

Updated by Michael Kay over 11 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.

Actions #6

Updated by O'Neil Delpratt over 11 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

Actions #7

Updated by O'Neil Delpratt over 11 years ago

  • Status changed from Resolved to Closed
  • Fixed in version set to 9.4.0.6

Please register to edit this issue

Also available in: Atom PDF