Difference between revisions of "SolvingClassLoaderProblems"
Line 15: | Line 15: | ||
In this case the exception was caused by a trivial stupid typo in the org.protege.common manifest but I was confused at the time and did not figure this out. So the first item of confusion here might be the question of which class loader is causing the problem. One might somehow think that this is being caused by the class loader for the org.protege.editor.owl bundle because, in some vague and undefined sense, this sequence of events seemed to be triggered in that bundle. But this is not how class loaders work. Actually the class loader that got into trouble (before delegation is taken into account) is the class loader for the org.coode.xml.XMLWriterImp class. This class loader is the org.semanticweb.owlapi bundle. | In this case the exception was caused by a trivial stupid typo in the org.protege.common manifest but I was confused at the time and did not figure this out. So the first item of confusion here might be the question of which class loader is causing the problem. One might somehow think that this is being caused by the class loader for the org.protege.editor.owl bundle because, in some vague and undefined sense, this sequence of events seemed to be triggered in that bundle. But this is not how class loaders work. Actually the class loader that got into trouble (before delegation is taken into account) is the class loader for the org.coode.xml.XMLWriterImp class. This class loader is the org.semanticweb.owlapi bundle. | ||
− | + | ||
This should have been enough for me to figure out what happened because (at this time) the org.semanticweb.owlapi bundle imported the package org.apache.commons.lang and the org.protege.common bundle exportedthe package org.apache.commons.lang package. There were very few things that could go wrong at this point but I didn't see it and I began to doubt my reasoning. | This should have been enough for me to figure out what happened because (at this time) the org.semanticweb.owlapi bundle imported the package org.apache.commons.lang and the org.protege.common bundle exportedthe package org.apache.commons.lang package. There were very few things that could go wrong at this point but I didn't see it and I began to doubt my reasoning. | ||
− | + | ||
To solve these types of problems I have created a bundle providing some servlets that debug class loading issues. The source for this bundle can be | To solve these types of problems I have created a bundle providing some servlets that debug class loading issues. The source for this bundle can be | ||
found in the svn repository | found in the svn repository |
Revision as of 22:56, October 25, 2007
In order to apply the techniques of this section the developer will need to have the ability to capture and navigate the output of a run command and must be able to compile a knopflerfish distribution (ant knopflerfish). Given this I will describe how to debug class loader exceptions (if they cannot be easily figured out and they are giving you a headache). So I recently saw the following exception:
java.lang.NoClassDefFoundError: org/apache/commons/lang/StringEscapeUtils at org.coode.xml.XMLWriterImpl.writeEntities(XMLWriterImpl.java:207) at org.coode.xml.XMLWriterImpl.startDocument(XMLWriterImpl.java:221) at org.coode.owl.rdf.rdfxml.RDFXMLWriter.startDocument(RDFXMLWriter.java:135) at org.coode.owl.rdf.rdfxml.RDFXMLRenderer.render(RDFXMLRenderer.java:87) at org.coode.owl.rdf.rdfxml.RDFXMLOntologyStorer.storeOntology(RDFXMLOntologyStorer.java:56) at uk.ac.manchester.cs.owl.OWLOntologyManagerImpl.saveOntology(OWLOntologyManagerImpl.java:370) at org.protege.editor.owl.model.OWLModelManagerImpl.save(OWLModelManagerImpl.java:368) at org.protege.editor.owl.OWLEditorKit.handleSave(OWLEditorKit.java:185) at org.protege.editor.core.ProtegeManager.saveEditorKit(ProtegeManager.java:187)
In this case the exception was caused by a trivial stupid typo in the org.protege.common manifest but I was confused at the time and did not figure this out. So the first item of confusion here might be the question of which class loader is causing the problem. One might somehow think that this is being caused by the class loader for the org.protege.editor.owl bundle because, in some vague and undefined sense, this sequence of events seemed to be triggered in that bundle. But this is not how class loaders work. Actually the class loader that got into trouble (before delegation is taken into account) is the class loader for the org.coode.xml.XMLWriterImp class. This class loader is the org.semanticweb.owlapi bundle.
This should have been enough for me to figure out what happened because (at this time) the org.semanticweb.owlapi bundle imported the package org.apache.commons.lang and the org.protege.common bundle exportedthe package org.apache.commons.lang package. There were very few things that could go wrong at this point but I didn't see it and I began to doubt my reasoning.
To solve these types of problems I have created a bundle providing some servlets that debug class loading issues. The source for this bundle can be found in the svn repository
http://smi-protege/repos/protege/protege4/small-projects/org.protege.osgi.debug/trunk
and once it is checked out it can be built with ant dist. The result of ant dist will be a relatively minimal OSGi distribution in the directory build/dist/equinox which allows the org.protege.osgi.debug bundle to run. To use this with an equinox distribution copy the files
javax.servlet_2.4.0.v200706111738.jar org.apache.commons.logging_1.0.4.v200706111724.jar org.eclipse.equinox.http.jetty_1.0.1.R33x_v20070816.jar org.eclipse.equinox.http.servlet_1.0.1.R33x_v20070816.jar org.eclipse.osgi.services_3.1.200.v20070605.jar org.mortbay.jetty_5.1.11.v200706111724.jar org.protege.osgi.debug.jar
into from the org.protege.osgi.debug distribution to the Protege 4 OWL editor's plugin directory. (Note the exclusion of the org.eclipse.osgi_3.3.1.R33x_v20070828.jar and org.eclipse.equinox.common_3.3.0.v20070426.jar files). Now when the OWL editor is started these bundles will automatically be loaded. One indicator that these bundles have been seen are the following messages on the console:
Oct 25, 2007 11:35:46 PM org.mortbay.http.HttpServer doStart INFO: Version Jetty/5.1.x Oct 25, 2007 11:35:46 PM org.mortbay.util.Container start INFO: Started org.mortbay.jetty.servlet.ServletHandler@c7e176 Oct 25, 2007 11:35:46 PM org.mortbay.util.Container start INFO: Started HttpContext[/,/] Oct 25, 2007 11:35:46 PM org.mortbay.http.SocketListener start INFO: Started SocketListener on 0.0.0.0:8080 Oct 25, 2007 11:35:46 PM org.mortbay.util.Container start INFO: Started org.mortbay.http.HttpServer@787144
These message merely indicate that the http servlet code been initialized.
Now the rest is easy. If you go to the page
and enter the class org/apache/commons/lang/StringEscapeUtils we find that there is no bundle that can load this class. But the plan was that the org.protege.common bundle should have seen this class. This fact takes us directly to the typo in the classpath for org.protege.common in the org.protege.common MANIFEST.
Futher we can check the imports and exports by going to the page
http://localhost:8080/debug/package
and selecting the org.semanticweb.owlapi bunde. We then see that this bundle imports the package org.apache.commons.lang from the org.protege.common bundle. This means that if org.protege.common can load the class
org/apache/commons/lang/StringEscapeUtils
then so should the org.semanticweb.owlapi bundle.