You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xerces.apache.org by Rob Walker <ro...@softsell.com> on 2002/05/09 15:25:40 UTC

SAX parser class loading

Apologies if this is a common question that you guys are sick of answering!

We use Xerces in an OSGi environment, where various dynamic classloaders 
are created to handle loading of classes related to specific service modules 
(actually termed "bundles" under OSGi).

Because of this, the Xerces JAR is not typically loaded from the System 
classloader. This causes us problems when we instantiate a SAX Parser, which 
seems to use Thread.getCurrentContextClassloader() to determine the 
classloader to use to find and instantiate it's various classes. Typically this 
method returns the System classloader if not specifically set by the thread in 
question.

To date, we've gotten around this by adding the following to the the run() method 
of any threads we create:


            setContextClassLoader(this.getClass().getClassLoader());


This is starting to become a pain though. Is there some reason that Xerces looks 
for it's thread's classloader in this way? And also, is there some neater, more 
generic way we can get around this?

TIA

-- Rob
SoftSell Business Systems, Ltd.
' testing solutions for a changing world '
 
+44 (20) 7488 3470
www.softsell.com
robw@softsell.com


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: Parsing special characters like '&'

Posted by Bob Jamison <rj...@lincom-asg.com>.
tom john wrote:

>I need to create xml document from string. if the text
>contains special characters like '&' it throws error.
>is there any solution for this... 
>may be some special feature that i can set for the
>parser.
>
>
>__________________________________________________
>Do You Yahoo!?
>LAUNCH - Your Yahoo! Music Experience
>http://launch.yahoo.com
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
>For additional commands, e-mail: xerces-j-user-help@xml.apache.org
>
>
>  
>
Tom,

A little method like this can maybe fix your
problem.  It processes a raw string into an
XML-compatible one:


String xmlString(String val)
{
  if (val==null)
    return val;
  StringBuffer buf = new StringBuffer();
  for (int i=0;i<val.length();i++)
      {
      char ch = val.charAt(i);
      if (ch=='&')
        buf.append("&amp;");
      else if (ch=='<')
        buf.append("&lt;");
      else if (ch=='>')
        buf.append("&gt;");
      else if (ch=='\'')
        buf.append("&apos;");
      else if (ch=='"')
        buf.append("&quot;");
      else
        buf.append(ch);
      }
  val=buf.toString();
  return val;
}



It will turn something like

"Rock & roll"

into

&quot;Rock &amp; roll&quot;






Hope this helps.


Bob Jamison
LinCom Corp



---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Parsing special characters like '&'

Posted by tom john <cy...@yahoo.com>.
I need to create xml document from string. if the text
contains special characters like '&' it throws error.
is there any solution for this... 
may be some special feature that i can set for the
parser.


__________________________________________________
Do You Yahoo!?
LAUNCH - Your Yahoo! Music Experience
http://launch.yahoo.com

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: SAX parser class loading

Posted by Rob Walker <ro...@softsell.com>.
> Rob Walker wrote:
> > This does always work - but it means every single thread that is created in the
> > VM has to remember to set it's context classloader - which is a total pain. In
> > every case, the solution is "set context classloader from this.class.classloader" -
> > which implies to me that Xerces could have this as a fallback option if a class is
> > not found through the thread context classloader.
> 
> I've already made the fix to the ObjectFactory class used by 
> Xerces2 to dynamically load the default parser config class. 
> Now it's just a matter of convincing everyone else that it 
> would be a good idea to make the same change in xml-commons 
> and in our modified JAXP impl.

Cool - and thanks Andy. 

It seems like a bit of a no brainer to me. The existing functionality can still be the 
standard. Just adds a nicer intermediate fallback attempt before throwing a class 
not found exception. So hopefully we can convince the xml-commons guys that 
this is an improvement too.

-- Rog


> 
> -- 
> Andy Clark * andyc@apache.org
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
> For additional commands, e-mail: xerces-j-user-help@xml.apache.org
> 


SoftSell Business Systems, Ltd.
' testing solutions for a changing world '
 
+44 (20) 7488 3470
www.softsell.com
robw@softsell.com


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: SAX parser class loading

Posted by Andy Clark <an...@apache.org>.
Rob Walker wrote:
> This does always work - but it means every single thread that is created in the
> VM has to remember to set it's context classloader - which is a total pain. In
> every case, the solution is "set context classloader from this.class.classloader" -
> which implies to me that Xerces could have this as a fallback option if a class is
> not found through the thread context classloader.

I've already made the fix to the ObjectFactory class used by 
Xerces2 to dynamically load the default parser config class. 
Now it's just a matter of convincing everyone else that it 
would be a good idea to make the same change in xml-commons 
and in our modified JAXP impl.

-- 
Andy Clark * andyc@apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: SAX parser class loading

Posted by Edwin Goei <ed...@sun.com>.
Rob Walker wrote:
> 
> > Are you saying that you tried your proposed solution on JDK 1.4 and got
> > it to work?  I don't know enough about your app to understand.  I think
> > we agree that the problem exists in JDK 1.4.  In addition, I think that
> > the proposed solution will probably still fail unless you are using JDK
> > 1.4 in a non-standard way.
> 
> The problem (and solution) are exactly the same under JDK1.3 and JDK1.4.
> Due to the nature of OSGi, which uses modular classloaders, the Xerces.jar is
> not on the classpath. It is loaded by a custom classloader.
> 
> >
> > I would expect that setting the context CL to your custom CL which has
> > access to the impl classes will always work, however.  Unfortunately, I
> > have not heard of a better solution to this problem yet.
> 
> This does always work - but it means every single thread that is created in the
> VM has to remember to set it's context classloader - which is a total pain. In
> every case, the solution is "set context classloader from this.class.classloader" -
> which implies to me that Xerces could have this as a fallback option if a class is
> not found through the thread context classloader.

In JDK 1.4, the FactoryFinder (package private) class is part of rt.jar
which means that if you use the usual class loading delegation model, it
will be loaded by the bootstrap CL.  Thus, the code

  FactoryFinder.class.getClassLoader()

will return the bootstrap CL and not your custom CL that has access to
the parser impl that you want to load.  The result is that the class
will still not be found.

-Edwin

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: SAX parser class loading

Posted by Rob Walker <ro...@softsell.com>.
> Are you saying that you tried your proposed solution on JDK 1.4 and got
> it to work?  I don't know enough about your app to understand.  I think
> we agree that the problem exists in JDK 1.4.  In addition, I think that
> the proposed solution will probably still fail unless you are using JDK
> 1.4 in a non-standard way.

The problem (and solution) are exactly the same under JDK1.3 and JDK1.4.
Due to the nature of OSGi, which uses modular classloaders, the Xerces.jar is 
not on the classpath. It is loaded by a custom classloader.

> 
> I would expect that setting the context CL to your custom CL which has
> access to the impl classes will always work, however.  Unfortunately, I
> have not heard of a better solution to this problem yet.

This does always work - but it means every single thread that is created in the 
VM has to remember to set it's context classloader - which is a total pain. In 
every case, the solution is "set context classloader from this.class.classloader" - 
which implies to me that Xerces could have this as a fallback option if a class is 
not found through the thread context classloader.

-- Rob

SoftSell Business Systems, Ltd.
' testing solutions for a changing world '
 
+44 (20) 7488 3470
www.softsell.com
robw@softsell.com


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: SAX parser class loading

Posted by Edwin Goei <ed...@sun.com>.
Rob Walker wrote:
> 
> >
> > Sorry to be late in the discussion.  The proposed fix may not solve your
> > problem starting w/ JDK 1.4.0.  The reason is that the code you refer to
> > or versions like it are part of the JDK platform and are loaded by the
> > bootstrap CL.  This means that the current CL will be the bootstrap CL
> > and will not see your impl unless it is on the bootstrap classpath.
> 
> Thanks for the response - not sure I follow it though.
> 
> We load the SAX libraries from the Xerces JAR through a custom OSGi
> classloader - which is where the problem comes in. We've already used this
> approach under JDK 1.4 and it has the same problem and same solutions. So I
> don't really understand how 1.4 changes the picture?

Are you saying that you tried your proposed solution on JDK 1.4 and got
it to work?  I don't know enough about your app to understand.  I think
we agree that the problem exists in JDK 1.4.  In addition, I think that
the proposed solution will probably still fail unless you are using JDK
1.4 in a non-standard way.

If you have not yet tried it on JDK 1.4, you can try this for yourself
by making changes to the FactoryFinder code and placing it in the
bootstrap classpath of JDK 1.4.  On Sun's JDK, one way is to use the
-Xbootclasspath/p option.

I would expect that setting the context CL to your custom CL which has
access to the impl classes will always work, however.  Unfortunately, I
have not heard of a better solution to this problem yet.

-Edwin

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: SAX parser class loading

Posted by Rob Walker <ro...@softsell.com>.
Edwin

> Rob Walker wrote:
> > 
> > Thread.getContextClassLoader() will typically return either "null" or the System
> > classloader unless the application code explicitly overrides this by using
> > setContextClassLoader on every thread it creates.
> > 
> > Either of these cases will definitely cause problems in a dynamic server
> > environment where the Xerces JAR is not necessarily on the system classpath
> > e.g. where it's part of a custom class loading strategy.
> > 
> > My suggestion would be twofold:
> > 
> > (i) if getContextClassLoader returns null, then try class.getClassLoader()
> > 
> > (ii) if getContextClassLoader returns a non-null value, but a ClassNotFound or
> > NoClassDef exception is thrown when attempting to instantiate using the
> > classloader from (i) then try using class.getClassLoader()
> > 
> > I think that would support most cases of both standard classpath usage, and
> > catch cases where dynamic classloaders are used (e.g. in servers).
> 
> Sorry to be late in the discussion.  The proposed fix may not solve your
> problem starting w/ JDK 1.4.0.  The reason is that the code you refer to
> or versions like it are part of the JDK platform and are loaded by the
> bootstrap CL.  This means that the current CL will be the bootstrap CL
> and will not see your impl unless it is on the bootstrap classpath.

Thanks for the response - not sure I follow it though.

We load the SAX libraries from the Xerces JAR through a custom OSGi 
classloader - which is where the problem comes in. We've already used this 
approach under JDK 1.4 and it has the same problem and same solutions. So I 
don't really understand how 1.4 changes the picture?

-- Rob

> 
> -Edwin
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
> For additional commands, e-mail: xerces-j-user-help@xml.apache.org
> 


SoftSell Business Systems, Ltd.
' testing solutions for a changing world '
 
+44 (20) 7488 3470
www.softsell.com
robw@softsell.com


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: SAX parser class loading

Posted by Edwin Goei <ed...@sun.com>.
Rob Walker wrote:
> 
> Thread.getContextClassLoader() will typically return either "null" or the System
> classloader unless the application code explicitly overrides this by using
> setContextClassLoader on every thread it creates.
> 
> Either of these cases will definitely cause problems in a dynamic server
> environment where the Xerces JAR is not necessarily on the system classpath
> e.g. where it's part of a custom class loading strategy.
> 
> My suggestion would be twofold:
> 
> (i) if getContextClassLoader returns null, then try class.getClassLoader()
> 
> (ii) if getContextClassLoader returns a non-null value, but a ClassNotFound or
> NoClassDef exception is thrown when attempting to instantiate using the
> classloader from (i) then try using class.getClassLoader()
> 
> I think that would support most cases of both standard classpath usage, and
> catch cases where dynamic classloaders are used (e.g. in servers).

Sorry to be late in the discussion.  The proposed fix may not solve your
problem starting w/ JDK 1.4.0.  The reason is that the code you refer to
or versions like it are part of the JDK platform and are loaded by the
bootstrap CL.  This means that the current CL will be the bootstrap CL
and will not see your impl unless it is on the bootstrap classpath.

-Edwin

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: SAX parser class loading

Posted by Rob Walker <ro...@softsell.com>.
> >The problem I'm guessing that you are running into is that
> >the Thread#getContextClassLoader is actually returning null
> >in your environment. Typically, this should not happen but
> >I guess there are probably reasons why it's implemented
> >that way.
> >
> >So from this perspective I can see the inherent problem. 
> >In this case, we should probably revert back to using 
> >Class#getClassLoader since we do need *some* class loader
> >in order to instantiate the objects we need. Have I hit
> >the cause of your problem?


Yep - I thought I'd explained it ok, but clearly not. Anyhow this is exactly the 
problem.

Thread.getContextClassLoader() will typically return either "null" or the System 
classloader unless the application code explicitly overrides this by using 
setContextClassLoader on every thread it creates.

Either of these cases will definitely cause problems in a dynamic server 
environment where the Xerces JAR is not necessarily on the system classpath 
e.g. where it's part of a custom class loading strategy.

My suggestion would be twofold:

(i) if getContextClassLoader returns null, then try class.getClassLoader()

(ii) if getContextClassLoader returns a non-null value, but a ClassNotFound or 
NoClassDef exception is thrown when attempting to instantiate using the 
classloader from (i) then try using class.getClassLoader()

I think that would support most cases of both standard classpath usage, and 
catch cases where dynamic classloaders are used (e.g. in servers).

TIA

-- Rob Walker

SoftSell Business Systems, Ltd.
' testing solutions for a changing world '
 
+44 (20) 7488 3470
www.softsell.com
robw@softsell.com


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: SAX parser class loading

Posted by Richard Zschech <ri...@cqrdata.com>.
I also have this problem with xerces 2 using 
Thread.getCurrentContextClassloader() in its object factory. I am 
loading the xerces parser with my own class loader and wish all the 
related xerces classes to use this class loader.
The method Thread.getCurrentContextClassloader() gets around my class 
loader and causes problems.
I would prefer you to use Class.getClassLoader() to get the appropriate 
class loader.

Thanks,
 From Richard.

Andy Clark wrote:

>Rob Walker wrote:
>  
>
>>Because of this, the Xerces JAR is not typically loaded from the System
>>classloader. This causes us problems when we instantiate a SAX Parser, which
>>    
>>
>
>Which problems?
>
>  
>
>>seems to use Thread.getCurrentContextClassloader() to determine the
>>classloader to use to find and instantiate it's various classes. Typically this
>>    
>>
>
>This is the prescribed way to dynamically load classes
>in Java2 and is recommended over the typcially used method,
>Class#getClassLoader. 
>
>There are a few cases where classes are dynamically loaded
>in Xerces2 (and for that matter Xerces 1.x as well). One
>place is JAXP. The factory classes are specified in a Jar
>service (META-INF/services) config file.
>
>The same strategy is used within the Xerces2 ObjectFactory
>which is basically code borrowed from the JAXP internal
>factory and which is used to dynamically load the config
>that the parser classes should be using.
>
>The problem I'm guessing that you are running into is that
>the Thread#getContextClassLoader is actually returning null
>in your environment. Typically, this should not happen but
>I guess there are probably reasons why it's implemented
>that way.
>
>So from this perspective I can see the inherent problem. 
>In this case, we should probably revert back to using 
>Class#getClassLoader since we do need *some* class loader
>in order to instantiate the objects we need. Have I hit
>the cause of your problem?
>
>This would require a change to the xml-commons JAXP code,
>the JAXP code in xml-xerces (copied from xml-commons but
>with modifications), *and* the ObjectFactory class since
>this was written from the JAXP code. Not too hard to do --
>I just want to make sure that this would fix the problem
>you're experiencing before I commit any changes.
>
>  
>
>>for it's thread's classloader in this way? And also, is there some neater, more
>>generic way we can get around this?
>>    
>>
>
>Not at the moment. We'd have to fix the code and then you'd
>have to actually use the version of Xerces incorporating
>those changes.
>
>  
>




---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: SAX parser class loading

Posted by Andy Clark <an...@apache.org>.
Rob Walker wrote:
> Because of this, the Xerces JAR is not typically loaded from the System
> classloader. This causes us problems when we instantiate a SAX Parser, which

Which problems?

> seems to use Thread.getCurrentContextClassloader() to determine the
> classloader to use to find and instantiate it's various classes. Typically this

This is the prescribed way to dynamically load classes
in Java2 and is recommended over the typcially used method,
Class#getClassLoader. 

There are a few cases where classes are dynamically loaded
in Xerces2 (and for that matter Xerces 1.x as well). One
place is JAXP. The factory classes are specified in a Jar
service (META-INF/services) config file.

The same strategy is used within the Xerces2 ObjectFactory
which is basically code borrowed from the JAXP internal
factory and which is used to dynamically load the config
that the parser classes should be using.

The problem I'm guessing that you are running into is that
the Thread#getContextClassLoader is actually returning null
in your environment. Typically, this should not happen but
I guess there are probably reasons why it's implemented
that way.

So from this perspective I can see the inherent problem. 
In this case, we should probably revert back to using 
Class#getClassLoader since we do need *some* class loader
in order to instantiate the objects we need. Have I hit
the cause of your problem?

This would require a change to the xml-commons JAXP code,
the JAXP code in xml-xerces (copied from xml-commons but
with modifications), *and* the ObjectFactory class since
this was written from the JAXP code. Not too hard to do --
I just want to make sure that this would fix the problem
you're experiencing before I commit any changes.

> for it's thread's classloader in this way? And also, is there some neater, more
> generic way we can get around this?

Not at the moment. We'd have to fix the code and then you'd
have to actually use the version of Xerces incorporating
those changes.

-- 
Andy Clark * andyc@apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org