Bug 45704

Summary: Failed to load logging.xml for JRE 1.5.0_16 and Webstart
Product: Log4j - Now in Jira Reporter: Andrejs Dembovskis <andrejs.dembovskis>
Component: ConfiguratorAssignee: log4j-dev <log4j-dev>
Status: RESOLVED FIXED    
Severity: major CC: nick
Priority: P2    
Version: 1.2   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   

Description Andrejs Dembovskis 2008-08-28 04:45:59 UTC
Due to changes in resource loader in JRE 1.5.0_16 and 1.6.0_7 (http://sunsolve.sun.com/search/document.do?assetkey=1-66-238628-1) log4j failed to load logging.xml file from jar (Webstart only). Problem happens if custom resource loader is used. Can you help?

log4j:ERROR Could not parse url [jar:logging.xml].
java.net.MalformedURLException: no !/ in spec
at java.net.URL.<init>(Unknown Source)
at java.net.URL.<init>(Unknown Source)
at java.net.URL.<init>(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
at org.apache.log4j.xml.DOMConfigurator$2.parse(DOMConfigurator.java:612)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:711)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:618)
at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:468)
at org.apache.log4j.LogManager.<clinit>(LogManager.java:122)
at org.apache.log4j.Logger.getLogger(Logger.java:117)
at myapp.Main.<clinit>(Main.java:94)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.continueLaunch(Unknown Source)
at com.sun.javaws.Launcher.handleApplicationDesc(Unknown Source)
at com.sun.javaws.Launcher.handleLaunchFile(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
log4j:WARN No appenders could be found for logger (com.btec.cds.Main).
log4j:WARN Please initialize the log4j system properly.
Comment 1 Nick Ebbutt 2008-09-26 13:43:12 UTC
I think this can be solved just by modifying line 762 in DOMConfigurator, in the method public void doConfigure(final URL url, LoggerRepository repository)

Instead of parser.parse(url.toString()) it seems to work OK if we use parser.parse(url.openConnection().getInputStream()).

The reason is that the url obtained via URL.toString() was broken for webstart apps in a jdk security patch for 1.5.0_16 and 1.6_07, to obscure the path to jar files in the webstart cache. openConnection still works

I built a patch with this fix and it seemed to work OK for our webstart apps
See my blog for more details, http://www.objectdefinitions.com/odblog/2008/fix-for-log4j-bug-45704-failed-to-load-loggingxml-for-jre-150_16-and-webstart/

Nick
Comment 2 Curt Arnold 2008-09-26 16:45:04 UTC
Passing the stream instead of the URL would result in relative URL's in entity references not properly resolving.  That is if you had a configuration file that looked like:

<!DOCTYPE log4j:configuration [
<!ENTITY A1 SYSTEM A1.xml>
]>
<log4j:configuration>
&A1;
</log4j:configuration>

if you only passed the stream, the parser would not know where to locate A1.xml.  If you passed a URL or a InputSource, then the parser would know how the resolve A1.xml.

Will have to look through the code, but it would seem the answer would be to pass the URL down through the stack instead of trying to convert the URL to a string and then back.
Comment 3 Nick Ebbutt 2008-09-29 02:26:46 UTC
Good observation, I didn't spot that. 

It looks like it will make this bug a fair bit more difficult to fix. There is no convenient method on DocumentBuilder to pass a URL instance in directly. I wonder if creating a relative URL based on the URL instance you get under webstart would even work, given how broken the webstart URL instance seems.

The fix I suggested does at least appear to make things work if there is a self-contained config.xml, which I am guessing is probably the majority of cases, but it would be good to find a perfect solution to this. Right now the best workaround I can think of is to take the xml config out of the jar, and make it available via http so it can be downloaded from the web app codebase. This could have advantages anyway, since that way to change the logging config you don't have to rebuild the jars, just change the log.xml on the server. I guess a fair few apps might do it this way already

Comment 4 Nick Ebbutt 2008-10-01 07:16:31 UTC
There is now a bug report relating to this issue on Sun's site
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6753651
Comment 5 Curt Arnold 2009-01-14 11:03:02 UTC
The previous bug has been marked as a duplicate of:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6746185


From the notation it appears to be fixed in 1.5.0_17.

Committed workaround in log4j 1.2 in rev 734483, extras in rev 734485.