You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by Paul Smith <ps...@apache.org> on 2004/06/15 05:53:39 UTC

JMSReceiver/ClassLoaders/Success+Dilema

Well, I have actually managed to work out how to get Chainsaw to work with 
the JMSReceiver and inside Web start.

There is a couple of problems however.  To summarise, the ClassLoader that 
is used to load a class MUST have access to any required dependencies, 
either via the Jars/directories that the ClassLoader manages, or it's 
_parent_ ClassLoader.

I am able to create a ClassLoader that loads classes from a local plugins 
directory, and can delegate to the Parent classloader as per the spec. 
However the JMSReceiver is bundled inside the log4j core jar file, and 
that class is loaded by Web start's JNLPClassLoader.  At the time of 
loading the JMSReceiver class, the JNLPClassLoader does have access to 
JMSReceiver class, but can't locate the other jms libraries, which are 
available via the _CHILD_ classLoader (this new PluginClassLoader).

So the dilema is that realistically for this to work, the JMSReceiver 
class needs to be loaded by the PluginClassLoader.  This means that we 
would need to remove the JMSReceiver from the core jar only for web start 
purposes, and have the user drop it into their local plugin directory 
(lets call this log4jJMSReceiver.jar), 
along with say, weblogic.jar, or whatever JMS specific impl is required. 
The classes and it's dependancies need to be available from the same 
ClassLoader level or higher.

Secondly, to be able to actually use these loaded classes requires the 
following line in LogUI's startup method:

System.setSecurityManager(null);

This basically turns off security checking for most things, and is allowed 
because Chainsaw is marked with the "all Permissions" permission.  If this 
line is not added, then when a class inside one of these Plugin jars tries 
to, say, read a System property, you get something like:

Caused by: java.security.AccessControlException: access denied 
(java.util.PropertyPermission weblogic.xml.debug read)

Removing the SecurityManager seems a bit harsh, and I propose that we only 
do this with the User's permission via a AppliciationPreference so they 
can explicitly decide this.  The classes loaded via the PluginClassLoader 
then effectively become trusted.

Given these ClassLoader issues, I wonder whether it is worth NOT 
distributing the JMSReceiver class inside the log4j core jar, as users 
could run into the same problems.

I would appreciate if anyone has any comments on this.

regards,

Paul Smith

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Re: JMSReceiver/ClassLoaders/Success+Dilema

Posted by Paul Smith <ps...@apache.org>.
>
> Have a look into at the o.a.l.helpers.Loader class. All log4j components use 
> (or should use) the Loader class to load components. Maybe you can tell the 
> Loader class to use your PluginClassLoader. The name PluginClassLoader is a 
> little misleading because it is not just plugins but all log4j components 
> such as Layouts and Appenders etc.
>

I hadn't thought about the name being a problem.  Hmmm, that is a good 
point.  I'll have to have a think about it, but if you have any 
suggestions on a more appropriate name, let me know.

I'll have a look into the Loader and Joran Actions.  Thanks for the 
pointers. (Altough with or house getting painted, it might take me a while 
before home is setup to do any work).

> You can easily write a joran action which creates an auxiliary classloader to 
> be used in conjunction with o.a.l.helpers.Loader for the length of the Joran 
> configuration session. We can even imagine making using an instance of the 
> Loader class which relies on that auxiliary classloader.
>
> It's kind of a big and intrusive change but one that I am confident should 
> work as long as the config file is customizable by the end user. So, is the 
> log4j.xml file part of the webstart files or is it something supplied by the 
> user?

The configuration file is not part of the web start or any log4j 
distribution.  It's simply a standard log4j.xml file one would normally 
have, albeit it's used to configure Plugins/Receivers rather than 
appenders.  We, and other users, would like to be able to switch easily 
between other configurations by choosing an xml file.

thanks for your reply.

cheers,

Paul

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Re: JMSReceiver/ClassLoaders/Success+Dilema

Posted by Ceki Gülcü <ce...@qos.ch>.
At 11:59 PM 6/16/2004, you wrote:

>>Web start might not be a marginal deployment scenario, but
>>Webstart+JMS probably is.  How many people will still use webstart
>>once 1.3 is released?
>JMS+Webstart may be a little more marginal, but I know of at least 2 
>people that would like it to work... :)  At any rate it is _annoying_ me 
>no end when something should work, and I can't get to work.  Call me 
>stubborn, but it's these "why can't I get it to work" situations that make 
>me want to do it any way.  Call it an Australian stubborness thing.  We 
>hate to lose. :)

I imagined something of the sort. :-)


>>You are right to observe that the same problem with occur with JDBC as
>>well. You could allow the user to set the TCCL as an *option* and
>>never by default. I still think that by setting our own classloader we
>>trying to do something Web-start is not designed for. However, if you
>>are willing to do the work, I would not want to spoil the fun.
>
>Is there any way you could think of that I could tweak the 
>JoranConfigurator so that I can tell it which ClassLoader to use? Does 
>that make sense?  When Chainsaw starts up, it checks if there is a 
>standard log4j.xml file that the user wishes to use for Configuration, and 
>if someone wants a JMS/DB Receiver to load each time Chainsaw launches, 
>then JoranConfigurator will need to be told to use the PluginClassLoader. 
>I don't mind making the change, but just would love your thoughts on the 
>matter.

Have a look into at the o.a.l.helpers.Loader class. All log4j components 
use (or should use) the Loader class to load components. Maybe you can tell 
the Loader class to use your PluginClassLoader. The name PluginClassLoader 
is a little misleading because it is not just plugins but all log4j 
components such as Layouts and Appenders etc.

You can easily write a joran action which creates an auxiliary classloader 
to be used in conjunction with o.a.l.helpers.Loader for the length of the 
Joran configuration session. We can even imagine making using an instance 
of the Loader class which relies on that auxiliary classloader.

It's kind of a big and intrusive change but one that I am confident should 
work as long as the config file is customizable by the end user. So, is the 
log4j.xml file part of the webstart files or is it something supplied by 
the user?




>cheers,
>
>Paul Smith

-- 
Ceki Gülcü

      For log4j documentation consider "The complete log4j manual"
      ISBN: 2970036908 http://www.qos.ch/shop/products/clm_t.jsp  



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Re: JMSReceiver/ClassLoaders/Success+Dilema

Posted by Paul Smith <ps...@apache.org>.
> We will eventually release log4j 1.3. The current situation will not last 
> forever.
>

That is true.

> Overriding the TCCL is quite a harmful operation with consequences 
> affecting the system as a whole.
>

Yes, you are very right, I have limited knowledge in this area, so I am 
happy that you picked me up on that.  I'll change it so that it does not 
need to use the TCCL.

>
> Web start might not be a marginal deployment scenario, but
> Webstart+JMS probably is.  How many people will still use webstart
> once 1.3 is released?
>
JMS+Webstart may be a little more marginal, but I know of at least 2 
people that would like it to work... :)  At any rate it is _annoying_ me 
no end when something should work, and I can't get to work.  Call me 
stubborn, but it's these "why can't I get it to work" situations that make 
me want to do it any way.  Call it an Australian stubborness thing.  We 
hate to lose. :)

> You are right to observe that the same problem with occur with JDBC as
> well. You could allow the user to set the TCCL as an *option* and
> never by default. I still think that by setting our own classloader we
> trying to do something Web-start is not designed for. However, if you
> are willing to do the work, I would not want to spoil the fun.

Is there any way you could think of that I could tweak the 
JoranConfigurator so that I can tell it which ClassLoader to use? Does 
that make sense?  When Chainsaw starts up, it checks if there is a 
standard log4j.xml file that the user wishes to use for Configuration, and 
if someone wants a JMS/DB Receiver to load each time Chainsaw launches, 
then JoranConfigurator will need to be told to use the PluginClassLoader. 
I don't mind making the change, but just would love your thoughts on the 
matter.

cheers,

Paul Smith

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Re: JMSReceiver/ClassLoaders/Success+Dilema

Posted by Ceki Gülcü <ce...@qos.ch>.
At 12:12 AM 6/16/2004, Paul Smith wrote:



>>The important questions to ask is why are the dependent JMS classes not 
>>available? In my opinion, it is a consequence of the web-start deployment 
>>scenario. How representative is the web-start deployment scenario? Not 
>>very representative if you ask me.
>
>I did a quick grep of the weblog for today (only a 14 hours window so far) 
>and there have been ~740 invocations of the Web start version of Chainsaw. 
>I think that that the Web start is becoming quite popular, and not just a 
>gimmic. (that's 52 launches / hour).

So far today

egrep -i chainsawWebStart.jnlp /x1/log/www/weblog|cut -d ' ' -f 
2|sort|uniq|wc -l

gives 52 for 4:25 hours. (It's 4:25 in the morning in California.) That's 
still a lot of people.

>I don't think requiring a user to go through the process of checking out 
>CVS to build everthing to run Chainsaw is very useful.  Even providing an 
>ant script with a series of Jars to include (with any JMS jars being added 
>as needed) is better, but not as elegant as Web start.

We will eventually release log4j 1.3. The current situation will not last 
forever.

>As I stated before, since the JMSReceiver gets loaded by the Web start 
>Classloader, it cannot find the dependencies (those actual implementation 
>classes that might be found in, say, weblogic.jar).  Since the 
>PluginClassLoader is a child of the Web start ClassLoader, it cannot see 
>them, and you get the infamous NoClassDefFoundError.
>
>Baring in mind that it is not 'log4j' having a classloader, but Chainsaw, 
>and yes I agree that it's a subtle point, but it is not that I am imposing 
>a Classloader on log4j. (more on this further down).

Overriding the TCCL is quite a harmful operation with consequences
affecting the system as a whole.

>>Log4j should not set the thread context class loader as this is an
>>important prerogative of J2EE containers. Actually, this line will cause
>>havoc when used within a container. For once, it will immediately
>>break JNDI. (The TCL was invented to allow JNDI context variables.) It
>>will actually break log4j itself which uses JNDI variables.
>>
>>Please don't bring the whole structure down in order to cater for this
>>marginal deployment scenario. If an elegant solution cannot be
>>provided, than it is better to recognize this fact and then to move
>>on. In this case, the wisest thing to do may be to declare that
>>JMSReceiver does not work with web-start.
>
>Your point on the TCCL is well taken.  I will remove that, and it _could_ 
>be worked around by having a Chainsaw singleton that represents the 
>classloader that Chainsaw itself only uses to load Receiver's and other 
>plugins.  It would be nice if the JoranConfigurator could use that 
>ClassLoader to find plugins from an xml file, but lets talk more about 
>that another time, your veto clearly states that you wish any ClassLoader 
>to be removed.
>
>Again I do not see Web start as a marginal deployment scenario, IMHO.

Web start might not be a marginal deployment scenario, but
Webstart+JMS probably is.  How many people will still use webstart
once 1.3 is released?

>JMSReceiver aside, the same issue will crop up with a DBReceiver, since 
>the JDBC driver would need to be hosted locally.  The driver impl becomes 
>the same issue as the JMS impl.  Don't you think it's is worthy to at 
>least attempt to make this application accessible?  Otherwise Chainsaw via 
>Web start can only read in log files and connect to sockets, which is only 
>about half or less of the number of scenarios that real people are using 
>it for.  We might as well forget about it.

You are right to observe that the same problem with occur with JDBC as
well. You could allow the user to set the TCCL as an *option* and
never by default. I still think that by setting our own classloader we
trying to do something Web-start is not designed for. However, if you
are willing to do the work, I would not want to spoil the fun.




-- 
Ceki Gülcü

      For log4j documentation consider "The complete log4j manual"
      ISBN: 2970036908 http://www.qos.ch/shop/products/clm_t.jsp  



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Re: JMSReceiver/ClassLoaders/Success+Dilema

Posted by Paul Smith <ps...@apache.org>.

On Tue, 15 Jun 2004, Ceki [iso-8859-1] G�lc� wrote:

>
> Paul,
>
> Please keep in mind that log4j can be placed quite high in the classloader 
> chain. Consider this as a side remark.
>

Yes, that is true, but usually when log4j is being used standalone (not 
Chainsaw).

>
> The important questions to ask is why are the dependent JMS classes not 
> available? In my opinion, it is a consequence of the web-start deployment 
> scenario. How representative is the web-start deployment scenario? Not very 
> representative if you ask me.
>

I did a quick grep of the weblog for today (only a 14 hours window so far) 
and there have been ~740 invocations of the Web start version of Chainsaw. 
I think that that the Web start is becoming quite popular, and not just a 
gimmic. (that's 52 launches / hour).

I don't think requiring a user to go through the process of checking out 
CVS to build everthing to run Chainsaw is very useful.  Even providing an 
ant script with a series of Jars to include (with any JMS jars being added 
as needed) is better, but not as elegant as Web start.

> I am quite worried about log4j starting to have its own
> classloader. Unless there is a compelling reason, I'd be much happier
> without PluginClassLoaderFactory. You just don't start spawning your
> own classloaders. It's usually very bad practice.
>
> How does placing log4jJMSReceiver.jar in a local plugin directory help?
>

As I stated before, since the JMSReceiver gets loaded by the Web start 
Classloader, it cannot find the dependencies (those actual implementation 
classes that might be found in, say, weblogic.jar).  Since the 
PluginClassLoader is a child of the Web start ClassLoader, it cannot see 
them, and you get the infamous NoClassDefFoundError.

Baring in mind that it is not 'log4j' having a classloader, but Chainsaw, 
and yes I agree that it's a subtle point, but it is not that I am imposing 
a Classloader on log4j. (more on this further down).


> Log4j should not set the thread context class loader as this is an
> important prerogative of J2EE containers. Actually, this line will cause
> havoc when used within a container. For once, it will immediately
> break JNDI. (The TCL was invented to allow JNDI context variables.) It
> will actually break log4j itself which uses JNDI variables.
>
> Please don't bring the whole structure down in order to cater for this
> marginal deployment scenario. If an elegant solution cannot be
> provided, than it is better to recognize this fact and then to move
> on. In this case, the wisest thing to do may be to declare that
> JMSReceiver does not work with web-start.
>

Your point on the TCCL is well taken.  I will remove that, and it _could_ 
be worked around by having a Chainsaw singleton that represents the 
classloader that Chainsaw itself only uses to load Receiver's and other 
plugins.  It would be nice if the JoranConfigurator could use that 
ClassLoader to find plugins from an xml file, but lets talk more about 
that another time, your veto clearly states that you wish any ClassLoader 
to be removed.

Again I do not see Web start as a marginal deployment scenario, IMHO.

JMSReceiver aside, the same issue will crop up with a DBReceiver, since 
the JDBC driver would need to be hosted locally.  The driver impl becomes 
the same issue as the JMS impl.  Don't you think it's is worthy to at 
least attempt to make this application accessible?  Otherwise Chainsaw 
via Web start can 
only read in log files and connect to sockets, which is only about half or 
less of the number of scenarios that real people are using it for.  We 
might as well forget about it.

> Unless, it was not clear 
from the above, my comment can be summarized 
as a 
> big fat -1. :-)

It was clear.

Paul


Re: JMSReceiver/ClassLoaders/Success+Dilema

Posted by Ceki Gülcü <ce...@qos.ch>.
Paul,

Please keep in mind that log4j can be placed quite high in the classloader 
chain. Consider this as a side remark.

At 05:53 AM 6/15/2004, you wrote:
>Well, I have actually managed to work out how to get Chainsaw to work with 
>the JMSReceiver and inside Web start.
>
>There is a couple of problems however.  To summarise, the ClassLoader that 
>is used to load a class MUST have access to any required dependencies, 
>either via the Jars/directories that the ClassLoader manages, or it's 
>_parent_ ClassLoader.
>
>I am able to create a ClassLoader that loads classes from a local plugins 
>directory, and can delegate to the Parent classloader as per the spec. 
>However the JMSReceiver is bundled inside the log4j core jar file, and 
>that class is loaded by Web start's JNLPClassLoader.  At the time of 
>loading the JMSReceiver class, the JNLPClassLoader does have access to 
>JMSReceiver class, but can't locate the other jms libraries, which are 
>available via the _CHILD_ classLoader (this new PluginClassLoader).

The important questions to ask is why are the dependent JMS classes not 
available? In my opinion, it is a consequence of the web-start deployment 
scenario. How representative is the web-start deployment scenario? Not very 
representative if you ask me.

>So the dilema is that realistically for this to work, the JMSReceiver 
>class needs to be loaded by the PluginClassLoader.  This means that we 
>would need to remove the JMSReceiver from the core jar only for web start 
>purposes, and have the user drop it into their local plugin directory 
>(lets call this log4jJMSReceiver.jar), along with say, weblogic.jar, or 
>whatever JMS specific impl is required. The classes and it's dependancies 
>need to be available from the same ClassLoader level or higher.

I am quite worried about log4j starting to have its own
classloader. Unless there is a compelling reason, I'd be much happier
without PluginClassLoaderFactory. You just don't start spawning your
own classloaders. It's usually very bad practice.

How does placing log4jJMSReceiver.jar in a local plugin directory help?

In order to answer this question, I had a peek at the recent
changes. In o.a.l.chainsaw.LogUI class these lines were added.

     ClassLoader classLoader = PluginClassLoaderFactory.create(new 
File(SettingsManager.getInstance().getSettingsDirectory() + File.separator 
+ "plugins"));
     Thread.currentThread().setContextClassLoader(classLoader);

Log4j should not set the thread context class loader as this is an
important prerogative of J2EE containers. Actually, this line will cause
havoc when used within a container. For once, it will immediately
break JNDI. (The TCL was invented to allow JNDI context variables.) It
will actually break log4j itself which uses JNDI variables.

Please don't bring the whole structure down in order to cater for this
marginal deployment scenario. If an elegant solution cannot be
provided, than it is better to recognize this fact and then to move
on. In this case, the wisest thing to do may be to declare that
JMSReceiver does not work with web-start.

>Secondly, to be able to actually use these loaded classes requires the 
>following line in LogUI's startup method:
>
>System.setSecurityManager(null);
>
>This basically turns off security checking for most things, and is allowed 
>because Chainsaw is marked with the "all Permissions" permission.  If this 
>line is not added, then when a class inside one of these Plugin jars tries 
>to, say, read a System property, you get something like:
>
>Caused by: java.security.AccessControlException: access denied 
>(java.util.PropertyPermission weblogic.xml.debug read)
>
>Removing the SecurityManager seems a bit harsh, and I propose that we only 
>do this with the User's permission via a AppliciationPreference so they 
>can explicitly decide this.  The classes loaded via the PluginClassLoader 
>then effectively become trusted.
>
>Given these ClassLoader issues, I wonder whether it is worth NOT 
>distributing the JMSReceiver class inside the log4j core jar, as users 
>could run into the same problems.


>I would appreciate if anyone has any comments on this.

Unless, it was not clear from the above, my comment can be summarized as a 
big fat -1. :-)

>regards,
>
>Paul Smith

-- 
Ceki Gülcü

      For log4j documentation consider "The complete log4j manual"
      ISBN: 2970036908 http://www.qos.ch/shop/products/clm_t.jsp  



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org