29

I have a directory to which a process uploads some .pdf files. This process is out of my control.

I need to make those files available through the website using Tomcat.

I have a directory /var/lib/tomcat5/webapps/test1 available to the web and I can see the files in it with a browser.

So, I created a symbolic link pointing at the directory with the .pdf files: /var/lib/tomcat5/webapps/test1/files/, but I can't see anything in that directory.

How can I enable symlinks in the test1 directory only? I don't want to enable symlinks everywhere, just so that directory with .pdf files is available to the web.

Jawa
  • 2,336
  • 6
  • 34
  • 39
jeph perro
  • 6,242
  • 26
  • 90
  • 124

7 Answers7

54

There are a few problems with the solution of creating a META-INF/context.xml that contains <Context path="/myapp" allowLinking="true">

The biggest issue is that if a conf/context.xml exists, the allowLinking in the <Context> there takes precedence over a <Context> in a META-INF/context.xml. And if the in the conf/context.xml does not explicitly define allowLinking, that's the same as saying allowLinking="false". (see my answer to a context precedence question)

To be sure that your app allows linking, you have to say <Context override="true" allowLinking="true" ...>.

Another issue is that the path="/myapp" is ignored in a META-INF/context.xml. To prevent confusion, it's best to leave it out. The only time path in a <Context> has any effect is in the server.xml, and the official Tomcat docs recommend against putting <Context>s in a server.xml.

Finally, instead of a myapp/META-INF/context.xml file, I recommend using a conf/Catalina/localhost/myapp.xml file. This technique means you can keep the contents of your META-INF clean, which is the guts of your webapp -- I don't like to risk mucking about in the guts of my webapp. :-)

Community
  • 1
  • 1
netjeff
  • 7,968
  • 4
  • 27
  • 30
  • 1
    big save.. thanks man. i had to put it into META-INF and add the override. (i think it doesn't work in the WEB-INF?) – dev Sep 16 '11 at 16:40
  • @piotr-czapla: Thanks for editing my answer to fix the WEB-INF to META-INF ! – netjeff Feb 06 '15 at 01:19
  • How would a files in this path be accessed from Java? E.g., if I wanted to create a File object to `/var/lib/tomcat5/webapps/test1/files/example.pdf` what would be the path string given to the constructor? – beldaz May 30 '16 at 09:00
  • @beldaz: You should create a new question (http://stackoverflow.com/questions/ask) rather than using comments. – netjeff Jun 02 '16 at 17:06
  • @netjeff it's fine, I was asking so that you could make your answer more complete, since many similar questions omit this small issue that confuses noobs like me. Files are simply accessed by their full file system path. – beldaz Jun 02 '16 at 21:35
  • Where is the `conf/context.xml` file when not in the `META-INF/context.xml` location? Is it in `..../content/[WEBAPP]/conf/context.xml`? or off catalina or tomcat or something? – Dave X Jun 11 '18 at 19:49
  • @DaveX: Regarding locations that are searched for context.xml and their precedence, see [my answer](https://stackoverflow.com/a/322535/41191) to a context precedence question that I mentioned in my original answer. – netjeff Jun 13 '18 at 04:54
  • this answer still allows any symbolic link found in the resources directory, so it doesn't answer the original question of "I don't want to enable symlinks everywhere, just so that directory with .pdf files is available" – Ryan Bennetts Jan 31 '22 at 03:20
17

Create a context.xml file in a META-INF directory in your web app containing:

<?xml version="1.0" encoding="UTF-8"?>

<Context path="/myapp" allowLinking="true">

</Context>

more here: http://www.isocra.com/2008/01/following-symbolic-links-in-tomcat/

kostmo
  • 6,222
  • 4
  • 40
  • 51
Loki
  • 29,950
  • 9
  • 48
  • 62
  • Yes, all I had to do was create a context.xml file : /var/lib/tomcat5/webapps/test1/META-INF/context.xml That link was very helpful. Thank you. – jeph perro Nov 24 '08 at 19:58
  • Thanks for this. Any idea how to configure tomcat (6) to always follow symlinks? – Tom Martin Nov 25 '08 at 21:09
8

Yes I know it's an old question, but I found a new solution, using mount with the --bind option instead of a symlink, and tomcat doesn't need any reconfiguring:

cd /var/lib/tomcat5/webapps/test1/

mkdir files

mount --bind /path/to/actual/upload/directory/files files

Mick
  • 81
  • 1
  • 1
8

This works different in Tomcat 8+

http://tomcat.apache.org/migration-8.html

<Resources allowLinking="true" />
weberjn
  • 1,840
  • 20
  • 24
4

There are 4 places where Context can live.

  1. tomcatdir/conf/server.xml
  2. tomcatdir/conf/context.xml
  3. tomcatdir/conf/Catalina/localhost/appname.xml
  4. tomcatdir/webapps/appname/META-INF/context.xml

In case of tomcat 8 allowlinking attribute should be specified not in Context but in Resources tag. My tomcatdir/conf/context.xml looks like this

<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
 <Resources allowLinking="true" cachingAllowed="true" cacheMaxSize="100000" />
</Context>

This solution works fine for me now. But I want to share also the mistake I had done before coming to this solution.

I had defined Resources both in tomcatdir/conf/server.xml and in tomcatdir/conf/context.xml. And allowLinking="true" was set only in tomcatdir/conf/server.xml.

What I found was that if you do not specify allowLinking it is equal to setting it to false. So I removed Resources tag from server.xml and left it only tomcatdir/conf/context.xml with the allowLinking="true" attribute in it.

Nare
  • 103
  • 8
1

I made it in this other way. I edit this other configuration file: apache-tomcat-7.0.33/conf/server.xml In Host tag I added:

<Context path="/data" docBase="C:\datos" debug="0" reloadable="true" crossContext="false"/>

So, you can acces via: http://localhost/data

Alberto Perez
  • 1,019
  • 15
  • 17
0

Adding following line into conf/context.xml enables softlinks for me on apache tomcat 8.5+

<Resources allowLinking="true" cachingAllowed="true" cacheMaxSize="100000">