Configure Symlinks for single directory in Tomcat - configuration

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.

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. :-)

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/

This works different in Tomcat 8+
http://tomcat.apache.org/migration-8.html
<Resources allowLinking="true" />

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

There are 4 places where Context can live.
tomcatdir/conf/server.xml
tomcatdir/conf/context.xml
tomcatdir/conf/Catalina/localhost/appname.xml
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.

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

Adding following line into conf/context.xml enables softlinks for me on apache tomcat 8.5+
<Resources allowLinking="true" cachingAllowed="true" cacheMaxSize="100000">

Related

MSBuild doing OctoPack before Publish

I have a C# .NET v4.6.1 compiled Azure Function, I am using Microsoft.NET.Sdk.Functions and I deploy it using my usual CI/CD Pipeline.
That being, a TeamCity MSBuild Build Step to create an OctoPack (because I have installed the OctoPack 3.6.3 NuGet package.
I then publish the resulting *.nupkg file to Octopus and Create a Release.
This is how I do all my Azure App Services, however as is nicely described in this post, compiled Azure Functions create a few extra files/folders when they are published to describe the entry point for the Function.
I can see (in the TeamCity build logs) that these extra files/folders are created by MSBuild (15.3.409.57025) but only AFTER it has prepared the OctoPack. Meaning my OctoPack artifact does not contain the necessary function specific folder(s) with the function.json file nor the functionsSdk.out.
I have managed to get around this issue by doing an extra TeamCity NuGet Pack Build Step to build the OctoPack again. I also had to create a *.nuspec file in the project root, where I tell NuGet Pack to include everything (see below) because using just the *.csproj file also ignored the extra folder/files.
<files>
<file src="bin\Release\net461\**\*.*" />
</files>
This works because it runs after the MSBuild Step and the extra folders/files are present. It will also be robust enough to support other Functions when are added to the Project going forward.
The need for this extra step and the *.nuspec file seems unnecessary. Can anyone see where I went wrong and why MSBuild seems to have the sequence of Publish and OctoPak wrong?
This could be a reason:
If the section exists, OctoPack by default won't attempt to
automatically add any extra files to your package, so you'll need to
be explicit about which files you want to include. You can override
this behavior with /p:OctoPackEnforceAddingFiles=true which will
instruct OctoPack to package a combination of files using its
conventions, and those defined by your section.
https://octopus.com/docs/packaging-applications/creating-packages/nuget-packages/using-octopack
Another idea — broken .csproj file. Please check it.
Maybe, during the merge these two lines were reordered:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\OctoPack.3.6.3\build\OctoPack.targets" Condition="Exists('..\packages\OctoPack.3.6.3\build\OctoPack.targets')" />
There should be Microsoft.CSharp.targets first. Order matters.
Workaround: OctoPack running after publish
<Target Name="SetRunOctoPack">
<PropertyGroup>
<RunOctoPack>true</RunOctoPack>
</PropertyGroup>
</Target>
<Target Name="AfterPublish" DependsOnTargets="SetRunOctoPack">
<CallTarget Targets="OctoPack"/>
</Target>

CSS not found for web app using Apache Tomcat 7.0

I have a web app that I have been developing from within Eclipse IDE and have been testing using a Tomcat sever, within Eclipse. Throughout development I've had no issues with CSS files being inaccessible.
Now I'm at a point where I'm using a standalone instance of Apache Tomcat and my CSS files are simply not found? When I try to access them via their URL a 404 error is produced. The location of a CSS file within my project appears to make no difference; I have tried it in a css/ folder and in the root folder of unfiltered pages.
I don't believe this to be an issue with the link I'm referring to the files with.
CSS & Page Location
-- OpportunityTracking (unpacked .war)
-- webapps
-- login.xhtml
-- bootstrap.css
CSS Reference in login.xhtml
<link rel="stylesheet" type="text/css" href="/OpportunityTracking/bootstrap.css" />
web.xml
<display-name>OpportunityTracking</display-name>
...
<mime-mapping>
<extension>css</extension>
<mime-type>text/css</mime-type>
</mime-mapping>
This project was set up as a Maven project however, the javax.faces jar was added as a dependency outside of Maven. Originally, javax.faces-2.1.26.jar was included as a referenced library in the eclipse project.
When faced with an unrelated issue, I removed this reference and included javax.faces-2.2.13.jar as a Maven dependency. In doing this, I appeared to resolve my original issue of CSS and Images not being found.
Update: I suffered this issue again and explored the issue further. By creating a 'Resources' folder in the 'webapps' folder, and referencing the css files from here, I found that all access issues were resolved

can not find cas.log for apereo/cas 4

I need to configire an apereo/cas in a few of days.
First I build the cas.war 4.2.2 according to https://github.com/apereo/cas-overlay-template. And then I deployed it in tomcat 8.0.36. After I start up the tomcat, I can login by the sample user(casuser: Mellon), but I can't find the cas.log file in tomcat/logs folder and other place by find / -name cas.log.
I have copied the log4j2.xml to /etc/cas/ as per the reference. Besides, I can't any error in tomcat/logs.
Did some one solve this problem or have a clue?
By the way, the log4j2 xml is available at https://github.com/apereo/cas-overlay-template/blob/master/etc/log4j2.xml.
Your log4j file describes where the log should be found. You'll file the location inside a file appender.
Your logging configuration doesn't specify a path so the files are going to end up in whatever the current directory is when you start tomcat or whatever tomcat sets the working directory to. That probably isn't what you want.

Configuration path of Log4j2

I am trying to adopt Log4j2 to my project. Since my Java Application is packeted in a JAR file. I don't want "log4j2.xml" configuration packaged inside of JAR file. I am trying to learn how configuration file works from "http://logging.apache.org/log4j/2.x/manual/configuration.html"
But seems there is no clear instruction regarding altering the configuration file path of the Log4j2.
After googling about this topic I found something like "Referencing log4j config file within executable JAR" Referencing log4j config file within executable JAR, But this solution is not available any more according to "http://logging.apache.org/log4j/2.x/manual/migration.html" (if I understand it correctly).
So I am wondering if someone have any idea about this issue.
Thanks
You can set the system property to specify the configuration path.
set the
"-Dlog4j.configurationFile="D:\learning\blog\20130115\config\LogConfig.xml"
in VM arguments. replace
"D:\learning\blog\20130115\config\LogConfig.xml"
to your configuration path.
Put the log4j2.xml file in resource directory in your project so that the log4j will locate files under class path automatically.
Loading log4j2.xml file from the customized location-
You can use the System property/ VM arguments- Dlog4j.configurationFile=file:/path/to/file/log4j2.xml
This will work for any web application.
For some legacy applications, you can create a class for loading log4j2.xml/ log4j2.properties from the custom location on the machine like- D:/property/log4j2.xml
Using any of these approach,during application startup, the log4j2.xml file from the src/resources folder will be overridden by the custom location log4j.xml file.
Try using -Dlogging.config=Path_to_your_file

Load a context/servlet at startup in Tomcat *WITHOUT* changing deployment descriptor (web.xml)

I've got a foo.war file from a third-party vendor. I've defined a context in my Tomcat configuration by creating conf/Catalina/localhost/foo.xml that contains:
<Context docBase="/path/to/foo.war" ...> ... </Context>
I want Tomcat to load up the foo context at startup. But the WEB-INF/web.xml (deployment descriptor) in the foo.war file does not include a <load-on-startup>, so Tomcat waits until the first request. I'd really rather not unpack the third-party foo.war to edit their web.xml. Plus, I'd have to do it every time the vendor releases a new version of their .war.
Is there any way within Tomcat configuration to tell Tomcat to load the foo context at startup? I know that within the <Context> element you can set parameters, env vars, etc without editing the web.xml. But I can't find anything in the Tomcat docs about loading on startup.
This is tricky. You're limited by the conventions of Tomcat and other containers, so there's no straightforward solution.
You could use the global web.xml to initialize specific servlets and/or JSPs from the .war using the <load-on-startup> element. This is the only way I know of to force load-on-startup without modifying the .war file or the WEB-INF/web.xml inside it. Note that you may need to initialize the servlets and JSPs using different names/paths to avoid conflicts.
Of course, doing it that way means you have to know enough about the .war to initialize the app, which might mean looking at its web.xml to determine what to load. This might defeat the purpose, since it's not exactly a hands-off approach to loading just any .war on startup. But with a little extra work, you could write a script that extracts the necessary information from the .war file's web.xml and adds it to your global web.xml automatically.
Now, if you're willing to consider script writing to modify the .war file, you could just write a script that extracts WEB-INF/web.xml from the .war file, adds <load-on-startup> child elements to all the <servlet> elements, and updates the .war with the new copy. I'm not sure what environment you're using to run Tomcat, but here's an example bash script that would do the job:
#!/bin/sh
TEMPDIR=/tmp/temp$$
WARFILE=/path-to-tomcat/webapps/foo.war
mkdir -p $TEMPDIR/WEB-INF
pushd $TEMPDIR
unzip -qq -c $WARFILE WEB-INF/web.xml \
| sed 's#</servlet>.*#<load-on-startup>99</load-on-startup></servlet>#' \
> WEB-INF/web.xml
zip -f $WARFILE WEB-INF/web.xml
popd
rm -rf $TEMPDIR
You could run this script or something similar as part of your Tomcat startup. Hope this helps.