Including Files Into Tomcat’s server.xml Using XML Entity Includes

April 29 2010

11 comments 0
motif

Once in a while I get questions about whether Apache Tomcat implements a way to include other files in , Tomcat’s main file.  The answer is that there is a way to do it, and that Tomcat didn’t have to implement a new feature for it to work.  The way to do it is: XML entity includes.

XML is a featureful and flexible data file format, and one thing that makes it helpful is that the XML parsers can be generic (think non-custom code), and because they can be generic, many different software projects can use the same parser code.  If the parser code can be shared, then all the features added to the parser can be available to all of the software projects that use the parser.  A great example of this is: it is common for us to want to include an additional file into a configuration file, so someone along the way added entity includes to the XML standard, then the XML parsers implemented it.  Tomcat got it “for free”.

Here’s how to include a file in your Tomcat’s server.xml.  Edit your server.xml, and at the very top of the file, right after any <?xml> declaration line (that’s optional), put the following DOCTYPE declaration to define a file entity:

This markup means that this document’s name is “server-xml”, and we’re defining a new entity named “connector1-config” which the XML parser can find in a file named “connector1-config.xml”.  You can name your entities anything you want, as long as the parser accepts the characters you use.  I suggest just using alpha-numeric characters and dash, to keep it simple.  It turns out that if you don’t specify an absolute path to the file, the parser will look for the file in the same directory as the file that includes it, so the parser will look in Tomcat’s conf/ directory.

But, we haven’t yet used the connector XML entity we defined at the top of server.xml.  At the point in the file where we want the parser to insert the connector’s XML, we need only to write “@connector1-config;” like this:

Then, in your connector1-config.xml file put the following XML snippet:

Using this include mechanism, you may include any file that resides in the same directory as Tomcat’s server.xml file.

If, instead, you want to include a file in another directory, where your Tomcat JVM user has read permission to the file, you can specify an absolute path when you define the entity, like this:

You use this entity the same way, just by placing “&connector1-config;” wherever you want the XML snippet included.


We'd love to hear your opinion on this post


11 Responses to “Including Files Into Tomcat’s server.xml Using XML Entity Includes”

  1. I got this error while i try to change like this
    java.net.MalformedURLException: For input string: “%5Capache-tomcat-5.5.30%5Cconf%5Cserver.xml”

  2. Does this work on windows? I am getting the same error as anonymous – it looks like tomcat is trying to build an expanded system ID that embeds the path name in the URL: file://C:\tomcat\… This then gets escaped and garbled by the XML parser resulting in MalformedURLExceptions.

    Is this a tomcat bug or am I doing something wrong?

  3. @John: This technique does work on Windows. Try specifying your file paths like /tomcat/something instead of c:\tomcat\something. Also, I would guess that the newer your Tomcat release version and JVM version, the more likely it is for this to work on Windows. Try it and let us know.. Cheers!

  4. I’m able to get this to work with a full URL – file:///tomcat/something – but not with a relative URL. I’ve got a file name “non-clustered.xml” that I’d like to include that lives in the same directory as server.xml – but it only seems to work if I specify the full path name, which isn’t very portable. I’m using tomcat 6.0.18.

  5. This is brilliant – I’m about to start building out our tomcat Puppet module and this is a nice easy way to load ‘fragments’ without having to parse all of server.xml.

  6. @John: Thanks for the info. Yeah, it probably does require an absolute filesystem path.
    @Dick: Yeah, it’s not for everyone, but for some of us it’s just the ticket!

  7. Is there a way to include several files using their wildcard names somedir/*.xml?

    • Thanks for this post. Can we set path dynamically using system property ?
      I tried this <!ENTITY connector SYSTEM "${private.path}/testConnector.txt
      but was getting below error? Could you please suggest? Thanks
      SEVERE: Catalina.stop:
      java.net.MalformedURLException: no protocol: ${private.path}/testConnector.txt

  8. Is there a way to include a file from a different drive? For example:
    the C:/ drive is where my tomcat is installed, but i want to reference a file located on my W:/ drive.

    I tried making a symlink ( mklink /D linkName W:\linklocation ) but that doesn’t follow the symlink. It will follow a directory junction through, but you can’t make a directory junction between folders if the drive you are linking to is not a local volume (In my case it is not)mklink.

    Yes, I know the issues with this, but I want to see if it can be done.

  9. You can include a relative path using the following syntax for the file name: “file:conf/connector1-config.xml”

    In that case, the path is relative to the current directory, not the directory containing server.xml.

    This works for tomcat 7.0.27 and jvm 1.7.0_04, both on Windows and Linux. I haven’t tested other versions.

  10. this worked for me<!DOCTYPE document [

    ]>