You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Jacob Kjome <ho...@visi.com> on 2007/01/10 06:16:08 UTC

Re: can log4j.properties be loaded by a server rather than app class loader by default?

At 06:30 PM 1/9/2007, you wrote:
 >I'm just curious if log4j guarantees that it would load the file that
 >resides in WEB-INF/classes,
 >as opposed to a similar named class loaded by a parent class loader.
 >
 >P.S. Because in general, if i understand correctly, a call like
 >
 >getClass().getClassLoader().getResource("WEB-INF/config/my_log4j.properties");

Assuming the "WEB-INF" directory is in the classpath, which it isn't 
unless you've got some custom setup.  Do you mean?...

getClass().getClassLoader().getResource("my_log4j.properties");

That would be correct.

You may be thinking of...

servetContext.getResource("/WEB-INF/config/my_log4j.properties");

Of course in that case you are guaranteed to you get your own 
resource because the servlet context  of your webapp can only see 
it's own WEB-INF directory, not that of any other app.

 >could return a URL from the parent class loader which would be not
 >what is intended.

Assuming that you are not using servlet-spec recommended classloading 
behavior, which Tomcat implements, but not all servers implement.  If 
you are using Tomcat, then making this call from a class residing 
inside a jar in WEB-INF/lib or WEB-INF/classes will look to the 
latter first, the former second, and the parent classloader third.

 >This method will first search the parent class loader for the resource;
 >if the parent is null the path of the class loader built-in to the virtual
 >machine is searched.
 >That failing, this method will invoke findResource(String) to find the
 >resource.
 >http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ClassLoader.html#get
 >Resource(java.lang.String)

Your general instinct is correct.  You should be wary of this 
issue.  If you want a better guarantee, load your resources from your 
own package and make sure your own package only exists in one place 
within the appserver.  Then no matter what classloader it gets loaded 
from, you know it's the one you want.

Jake



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


Re: can log4j.properties be loaded by a server rather than app class loader by default?

Posted by Jacob Kjome <ho...@visi.com>.
At 11:19 AM 1/12/2007, you wrote:
 >Jacob Kjome <hoju <at> visi.com> writes:
 >> <quote>
 >>
 >getClass().getClassLoader().getResource("WEB-INF/config/my_log4j.properties");
 >> </quote>
 >>
 >> The above is totally invalid because the "WEB-INF" directory is not
 >(normally)
 >> in the classpath.
 >Well, it raised my brows too, i guess somehow it is in the classpath,
 >because it
 >works even in my from-scratch workspace.

Well, don't count on this behavior.  It is totally non-standard and 
will fail in most J2EE server environments.

 >> ...and Tomcat's classloading is implemented by Tomcat.  Please read up on
 >> Tomcat's classloading behavior before asking any more questions 
about this.
 >> Tomcat inverts the classloader delegation to use child-first, or 
parent-last,
 >> classloading behavior.  Well, it does that initially.  Once it 
can't find the
 >> resource locally, then it reverts back to normal parent-first delegation.
 >I misspoke, i meant whether log4j didn't rely on ClassLoader.getResource, and
 >somehow gave a preference to the archive the resource is loaded from. But how
 >can it determine the location of the archive on the filesystem for J2SE apps?

Log4j's autoconfiguration looks up "log4j.xml" and "log4j.properties" 
in the root of the classpath.  The first one the classloader finds 
for it is used (with log4j.xml being searched for first and 
log4j.properties second).  It's up to the classloader to find the 
resource.  Log4j has no say about where the classloader chooses to 
load the resource from.  Note that, after the fact, one can determine 
where the resource was loaded from by looking at the result of 
getResource("log4j.xml").toExternalForm().  But there's no way to 
tell the classloader to load it from a specific jar or specific 
directory beforehand.

 >
 >On the other hand, WebSphere 6 has a setting of PARENT LAST vs. PARENT first,
 >and a WAR Classloader Policy of WAR vs. Application.

Yep, and Tomcat implements PARENT_LAST for it's webapps by default, 
though it may be different when Tomcat is used as the servlet 
container for a Full J2EE stack such as JBOSS.  When I talk about 
Tomcat's behavior, I mean in Standalone mode, not used as an embedded 
servlet container.

 > >class.getClassLoader.getResource("com/mypackage/myresources/myResour
 >ce.properties");
 >Yes, i was just trying to determine if it was safe to make 
resources easier to
 >find but not namespacing them when they are module-specific. So 
far, it appears
 >that is only safe when ServletContext.getResource is used.
 >

That's the only guaranteed way, though Log4j autoconfiguration 
mechanism will still attempt to configure Log4j as soon as the 
LogManager class is loaded up, which will probably happen before your 
servlet context listener gets called, as it occurs in a static block 
inside LogManger.  There's a system property option to turn off 
autoconfiguration, but its on by default (something like 
-Dlog4j.autoconfigure=false, but you'll have to verify whether that's 
the correct system property name).

 >Thanks.


Jake


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


Re: can log4j.properties be loaded by a server rather than app class loader by default?

Posted by Reshat Sabiq <cr...@argushealth.com>.
Jacob Kjome <hoju <at> visi.com> writes:
> <quote>
> getClass().getClassLoader().getResource("WEB-INF/config/my_log4j.properties");
> </quote>
> 
> The above is totally invalid because the "WEB-INF" directory is not (normally)
> in the classpath.
Well, it raised my brows too, i guess somehow it is in the classpath, because it
works even in my from-scratch workspace.
> ...and Tomcat's classloading is implemented by Tomcat.  Please read up on
> Tomcat's classloading behavior before asking any more questions about this. 
> Tomcat inverts the classloader delegation to use child-first, or parent-last,
> classloading behavior.  Well, it does that initially.  Once it can't find the
> resource locally, then it reverts back to normal parent-first delegation.
I misspoke, i meant whether log4j didn't rely on ClassLoader.getResource, and
somehow gave a preference to the archive the resource is loaded from. But how
can it determine the location of the archive on the filesystem for J2SE apps?

On the other hand, WebSphere 6 has a setting of PARENT LAST vs. PARENT first,
and a WAR Classloader Policy of WAR vs. Application.
 >class.getClassLoader.getResource("com/mypackage/myresources/myResource.properties");
Yes, i was just trying to determine if it was safe to make resources easier to
find but not namespacing them when they are module-specific. So far, it appears
that is only safe when ServletContext.getResource is used.

Thanks.


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


Re: can log4j.properties be loaded by a server rather than app class loader by default?

Posted by Jacob Kjome <ho...@visi.com>.
Quoting Reshat Sabiq <cr...@argushealth.com>:

> Jacob Kjome <hoju <at> visi.com> writes:
>
>
>getClass().getClassLoader().getResource("WEB-INF/config/my_log4j.properties");
> ...
> > getClass().getClassLoader().getResource("my_log4j.properties");
> ...
> > servetContext.getResource("/WEB-INF/config/my_log4j.properties");
> ...
> > Assuming that you are not using servlet-spec recommended classloading
> > behavior, which Tomcat implements, but not all servers implement.  If
> > you are using Tomcat, then making this call from a class residing
> > inside a jar in WEB-INF/lib or WEB-INF/classes will look to the
> > latter first, the former second, and the parent classloader third.

> Are you referring to ClassLoader.getResource here? Because

Yes

>
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletContext.html#getResource(java.lang.String)
> says:
> This method has a different purpose than java.lang.Class.getResource, which
> looks up resources based on a class loader. This method does not use class
> loaders.
>

Which is exactly what I pointed out.  I must not have made myself clear enough. 
servletContext.getResource() looks up resources within the servlet context and
has nothing whatsoever to do with classloading.  Your example mixed up the two
concepts...

<quote>
getClass().getClassLoader().getResource("WEB-INF/config/my_log4j.properties");
</quote>

The above is totally invalid because the "WEB-INF" directory is not (normally)
in the classpath.  The only way your example would work using the path you
provided is (also notice the addition of prefixed slash on the path)...

servletContext.getResource("/WEB-INF/config/my_log4j.properties");

> Something doesn't add up, because ClassLoader.getResource is implemented by
> the
> JRE, and not Tomcat. Are you saying that Tomcat uses some absolute paths to
> work
>
> around ClassLoader.getResource delegation to parent class loader by default?
>

...and Tomcat's classloading is implemented by Tomcat.  Please read up on
Tomcat's classloading behavior before asking any more questions about this. 
Tomcat inverts the classloader delegation to use child-first, or parent-last,
classloading behavior.  Well, it does that initially.  Once it can't find the
resource locally, then it reverts back to normal parent-first delegation.

> P.S. In this case, we have an object, called by axis so we don't have a
> ServletContext,
> although if this was refactored, to use ServletContextListener,
> i guess we'd be able to use ServletContext.getResource.
>

Please note what I stated in my previous email.  If you put your resource in a
unique package, such that it can't possibly clash with another pre-existing
naming scheme, then you don't have to worry about picking up the wrong
resource, because there won't ever be a case where two resources of the same
name are in the same package.  For instance...

class.getClassLoader.getResource("com/mypackage/myresources/myResource.properties");

Now the only thing you have to worry about is where your class is in relation to
the resource.  If the resource being loaded is in a child classloader in
relation to where the class doing the loading is, then the class in the parent
classloader won't be able to see the resource.  At this point, you can solve
that using the thread context classloader.

Jake

> Thanks.
>



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


Re: can log4j.properties be loaded by a server rather than app class loader by default?

Posted by Reshat Sabiq <cr...@argushealth.com>.
Jacob Kjome <hoju <at> visi.com> writes:

>getClass().getClassLoader().getResource("WEB-INF/config/my_log4j.properties");
...
> getClass().getClassLoader().getResource("my_log4j.properties");
...
> servetContext.getResource("/WEB-INF/config/my_log4j.properties");
...
> Assuming that you are not using servlet-spec recommended classloading 
> behavior, which Tomcat implements, but not all servers implement.  If 
> you are using Tomcat, then making this call from a class residing 
> inside a jar in WEB-INF/lib or WEB-INF/classes will look to the 
> latter first, the former second, and the parent classloader third.
Are you referring to ClassLoader.getResource here? Because 
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletContext.html#getResource(java.lang.String)
says:
This method has a different purpose than java.lang.Class.getResource, which
looks up resources based on a class loader. This method does not use class 
loaders.

Something doesn't add up, because ClassLoader.getResource is implemented by the 
JRE, and not Tomcat. Are you saying that Tomcat uses some absolute paths to work

around ClassLoader.getResource delegation to parent class loader by default?

P.S. In this case, we have an object, called by axis so we don't have a
ServletContext, 
although if this was refactored, to use ServletContextListener,
i guess we'd be able to use ServletContext.getResource.

Thanks.


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