I traced TC 5.0 and Digester and suspect what could be the problem with external entities when only SYTEM is defined ie :
<!ENTITY appset1 SYSTEM "appset1.xml"> <!ENTITY appset2 SYSTEM "appset2.xml">
In Digester.java, at least in the 1.5 release, resolveEntity return null if publicId is null even if systemId is set.
To make it works, I just replaced :
--
if (entityURL == null){ return (null);
by ---
if (entityURL == null){ if (systemId == null) return (null); else entityURL = systemId; }
FYI, in resolveEntity we got as parms for previous app1&app2 entities declaration:
systemid="jndi:/localhost/myapp/WEB-INF/appset1.xml" and publicid=null
systemid="jndi:/localhost/myapp/WEB-INF/appset2.xml" and publicid=null
This hack will solve the resolution of entities presents in WEB-INF.
Henri,
I have great success using Digester inside a webapp and referencing entities like this with relative references. If you still find you need to do this, then something is either configured wrong, or the way that Tomcat uses Digester has changed recently.
Now for entities located outside webapp / WEB-INF.
I know what the spec say about entities outside WAR but there is many case where you should serve the SAME application for many customers, and where specific settings for each customer MUST exist outside WAR.
Let see my case :
if the entity is defined like this :
<!ENTITY appset1 SYSTEM "file:../etc/appset1.xml"> <!ENTITY appset2 SYSTEM "file:/var/www/customer1/etc/appset2.xml">
resolveEntity got systemId="file:../etc/appset1.xml" and systemId="file:/var/www/customer1/etc/appset2.xml"
So if you have to specify a resource somewhere on your system, outside the webapp you should :
1) Know what the appBase and use .. trick to get it (relative).
XML parser resolution of entity references has ***nothing*** to do with appBase or docBase. It has ***everything*** to do with making sure that you specify a correct URL to the parser. You will find that the correct URL for a web.xml file inside a webapp is (for Tomcat) something like "jndi://localhost/myapp/WEB-INF/web.xml", so trying to use ".." type references to go above the context's document root directory ("../../../etc/foo.xml") is not going to work, for the same reason that the following operations on a Unix filesystem will fail:
cd /var cat ../../etc/hosts
because you're trying to reference "above" the top of the filesystem.
Absolute "file:" URLs, as you've discovered, are the way to deal with this issue.
2) Give an absolute reference on the file system, which is bad when you want to use the .war for many customers.
Let consider the following layout for an ISP/ASP provider wich use the same application for many clients (running their own TC 5).
/var/www/customer1/etc/appset1.xml /var/www/customer1/etc/appset2.xml /var/www/customer1/var/tomcat5/... /var/www/customer1/var/tomcat5/webapps/themainapp.war
/var/www/customer2/etc/appset1.xml /var/www/customer2/etc/appset2.xml /var/www/customer2/var/tomcat5/... /var/www/customer2/var/tomcat5/webapps/themainapp.war
You could use the file:.. trick to go from /var/www/customerx/var/tomcat5/, which is the appBase to /var/www/customerx/etc, where the customer specific settings are located.
Now consider another layout for an ISP/ASP provider wich use the same application for many clients but using a shared TC5.
/var/www/customer1/etc/appset1.xml /var/www/customer1/etc/appset2.xml /var/www/customer1/webapps/themainapp1.war /var/www/customer1/webapps/themainapp1/WEB-INF/...
/var/www/customer2/etc/appset1.xml /var/www/customer2/etc/appset2.xml /var/www/customer2/webapps/themainapp2.war /var/www/customer2/webapps/themainapp1/WEB-INF/...
themainapp1.war and themainapp2.war are copy of or symlink to the generic themainapp.war and are decompressed at startup time.
TC 5 is in shared mode, so it live outside customer layout :
/var/tomcat5/...
You couldn't use anymore the file:.. trick to go from /var/tomcat5/, which is the appBase to /var/www/customerx/etc, where the customer specific settings are located.
As described above, you're trying to use an illegal URL, which goes above the top of the webapp's namespace. You'll need to use absolute "file:" or "http:" type URLs, or provide your own EntityResolver that does whatever you want it to do.
The only way to developpers and admins to have it works in both case is to set the current directory when web.xml is parsed to WEB-INF/.
Craig (author of Digester, by the way :-)
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]