java:comp/env is not bound - java

I currently have a few libraries in my $CATALINA_HOME/lib directory to handle some system/DB authentication. One of those files foo.jar contains a class that extends
org.apache.catalina.realm.DataSourceRealm
and is being used to authentication. This file needs to access a few properties that I'm storing in server.xml However, when attempting to access it I'm getting an error. The segment of code is as follows
try{
Context ctx = new InitialContext();
Context envCtx = (Context)ctx.lookup("java:comp/env");
String property = (String)envCtx.lookup("property");
} catch(Exception ex) {}
Any ideas?

You also need to have the associated ResourceLink in the context.xml for your app. For example, if your webapp is named foo, there should be a file called conf/Catalina/localhost/foo.xml with a
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Context>
<Context antiJARLocking="true">
<ResourceLink name="property"
type="classname"
global="propertyNameInGlobalNamingResources" />
...
</Context>
If you include a META-INF/context.xml with these links in your war file, tomcat will copy it out to the conf/Catalina/localhost/foo.xml the first time the app is deployed (though not any time after that as you are intended to make changes there and be able to deploy again without clobbering customization)

Related

Problem with Tomcat9 Context's docBase attribute

I am new to Tomcat deployment.
I found in Tomcat's document and it says this about <Context> tag's docBase attribute:
The value of this field must not be set unless the Context element is defined in server.xml or the docBase is not located under the Host's appBase.
Here is my problem:
I create a <Host> tag inside server.xml and set appBase="C:/xxx/"
create a xml file named ROOT.xml inside C:/xxx/ and add <Context docBase="../yyy" />
put index.html inside C:/yyy/
Why is it doesn't work when I try to browser localhost:8080/ ?
Doesn't it supposed to show the index.html inside C:/yyy ?
Summary
When you add appBase="C:/xxx" to server.xml, that means all your web appplications will be found in that directory. At that point you cannot then have a specific web app which defines its own redirection to another directory (a custom docBase) from within its own web application location. At that point, its docBase location has already been set to be the appBase directory.
A Different Approach
The ROOT.xml file that you created can be used to point to a location which is different from the appBase - but you cannot place that file inside the appBase directory (as noted above).
Instead you have to place it in $CATALINA_BASE/conf/[enginename]/[hostname]/ as described in this documentation page.
So, for me, that would be:
C:\tomcat_9_test\conf\Catalina\localhost\ROOT.xml
And its contents would simply be:
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="C:/yyy" />
Because this is outside of the docBase, this specific application can have a different location from all the other web applications in docBase.
Now, your C:\yyyy\index.html file will be served at http://localhost:8080/, as expected.
A Note on context.xml
What if you do not use this ROOT.xml file at all, but instead you create a ROOT folder in C:\xxx and then create a META-INF folder there, containing a context.xml file?
You could define <Context docBase="../yyy" /> in there. But it would be ignored (again, because the docBase is already set).

404 error when I redeploy a war on Wildfly

I tried to deploy a war file on Wildfly (commandline) by changing the name of the old file (say app.war to appOld.war) and copying a new file with the name app.war to the deployment folder.
On my other terminal, I can see the auto deploy scanner running and deploying the new file but when I try to access the app via URL, I get a 404.
No error shows up in the logs so I don't realize what is happening or what to do.
Thanks.
I think there is problem with your context root.
Because if you don’t set context root wildfly takes filename as your context root.
When you deploy file you just renamed try access <hostname>:<port>/appOld instead of <hostname>:<port>/app
Context root can be manually set set in /WEB-INF/jboss-web.xml
Here is the example of jboss-web.xml whit context root:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<context-root>/my-web-app</context-root>
</jboss-web>
So when you set it you should be able to access yout app at: <hostname>:<port>/my-web-app
Hope it helps.

How to override spring property param with Tomcat?

I have defined property in Spring application.
#Configuration
public class WebappConfiguration {
#Value("${ext.storage.path}")
private String extDirectoryPath;
public String getExtDirectoryPath() {
return extDirectoryPath;
}
}
Default value for ext.storage.path property is defined in application.properties file.
application.properties
ext.storage.path=/home/user/ext/
When I deploy WAR to tomcat with VM options -Dext.storage.path=/var/webapp-data/, this value is loaded successfully. But I would like to load property values more smarter from context files for every environment.
So I deploy the WAR to ROOT of Tomcat, name of WAR file is ROOT.war and it is exploded to ROOT directory. I created context file on path {CATALINA_BASE}/Catalina/localhost/ROOT.xml with following content.
ROOT.xml
<Context
docBase="/opt/webapp-tomcat/webapps/ROOT.war"
path=""
reloadable="true">
<Parameter name="ext.storage.path" value="file:/var/webapp-data/" override="true"/>
</Context>
Unfortunately, the param is not loaded according to the way, it has default value from application.properties.
EDIT:
After a little investigation, I put the Parameter into main context.xml file of Tomcat and the value is overridden.
<Parameter name="ext.storage.path" value="file:/var/webapp-data/" override="true"/>
The best technique I know of is to put environment-specific stuff into Tomcat's conf/context.xml file.
<Environment name="myApp/extStoragePath" type="java.lang.String" value="/var/data/myapp"/>
This defines a JNDI variable that you lookup in your code with something like this:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
String extStoragePath = (String) envCtx.lookup("myApp/extStoragePath");
You can also use this technique to load complex objects like database datasources etc. It has huge advantages:
The configuration is personal to the environment, not the application
You don't need to mess with Tomcat startup scripts
The same binary will run in DEV, UAT and PROD without modification. This much simplifies the build process.
Also, Spring provides a org.springframework.jndi.JndiObjectFactoryBean which can access JNDI from your spring configuration files.

How to access folder which is outside war file?

I have application which is having lots of PDF files , when I try to build a war file of my application due to pdfs its size converts to Gbz , so basically I want to remove the pdf file folder from the application ,put it some location and then build a war file and deploy it to tomcat.so ,is there any way I can read folder from my application which is outside the war file?
You can use the File class to work with files and directories on the local file system.
For example if if your pdf files are in a folder called pdf you can create a File object like so
File pdfsFolder = new File("\pdfs");
You need to have a separe folder on your server to store the pdf. You pass this folder location to your application (for example using globaresouces in server.xml, so your production path and local path are coming from the server rather than hardcoded in your app.). You access the given folder normally from java (new File(dir), Paths.get...). If there is no SecurityManager you can access any part of the filesystem from within your webapp.
For example your aplication META-INF/context.xml
<Context>
<ResourceLink global="PDFPath" name="PDFPath" type="java.lang.String"/>
</Context>
Your tomcat, inside server.xml
<GlobalNamingResources>
<Environment name="PDFPath" value="D:\\Data\\PDFs" type="java.lang.String" override="false"/>
</GlobalNamingResources>
In your code:
Context initCtx = new InitialContext();
Context envCtx = (Context)initCtx.lookup("java:comp/env");
String storagePath = (String) getContext().lookup("PDFPath");
File pdfDir = new File(storagePath);
ya its correct way but give the Tomcat user permission to access the Pdf file , which is use to avoid the file listing when the time of directly url access Ex (www.yourSite.com/pdf/ex.pdf)

How do I remove the root element of my Jetty webapp url?

I am running a Java webapp (let's call it mywebapp).
Currently I access my page in this webapp by pointing locally to:
http://localhost:9000/mywebapp/mystuff
However, I need to access it using:
http://localhost:9000/mystuff
How can I do this? I've tried messing with some confs, but to no avail...
This is my current root.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
<Set name="contextPath">/root</Set>
<Set name="war">
<SystemProperty name="app.webapps.path"/>/mywebapp.war
</Set>
</Configure>
Also tried:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
<Set name="contextPath">/</Set>
<Set name="war">
<SystemProperty name="app.webapps.path"/>/mywebapp.war
</Set>
</Configure>
I'm using Maven - not sure if that may be making the difference.
Thanks!
In order to set your context path to "/" you'll want to use a Context deployment.
Note: You MUST specify a context path string for path spec mapping reasons. An empty context path string "" is only valid as a mapping result from requests to the context root. See Section 12.2 of the servlet spec)
In Jetty 7.x, the context path assignment is handled by the AppProviders assigned to the DeploymentManager.
By default, on the Jetty Distribution, both the WebAppProvider and ContextProvider are enabled. This is important to know later, as it will influence your decisions on where to put the mywebapp.war file.
See the ${jetty.home}/start.ini file, and you'll see that it contains both the references to etc/jetty-webapps.xml and etc/jetty-contexts.xml
WebAppProvider's role is to pay attention to the ${jetty.home}/webapps/ directory for any deployable applications (such as *.war) and deploy them onto a context of the same name as the filename. In other words ${jetty.home}/webapps/MyApp-2.4.war is deployed into the context "/MyApp-2.4". There is also the special "root.war" reserved word that will deploy into the context "/". While this is the easiest deployment mechanism, it sacrifices control over the deployment specifics.
ContextProvider's role is to pay attention to the ${jetty.home}/contexts/ directory for any jetty-xml formatted deployable contexts. This deployment mechanism gives you the maximum control over the deployment, the xml file can control anything that is ultimately resolved to a org.eclipse.jetty.server.handler.ContextHandler base class, of which WebAppContext (wars / servlets / etc) are part of.
The most common use is to specify a WebAppContext based xml file, and control things such as what files and directories make up the web application, what temporary directory to use, and even what Context Path to use.
What you'll want to do is to is:
Make sure your ContextProvider based deployments are enabled in the start.ini (make sure that etc/jetty-context.xml is present)
Create a ${jetty.home}/contexts/mywebapp.xml that declares the <Set name="contextPath">/</Set> option.
If you have the etc/jetty-webapps.xml present in your start.ini, do not put your mywebapp.war in ${jetty.home}/webapps as that will cause the WebAppProvider to also deploy the same webapp and confusing your deployment.
Finally, you can see how this is done in the jetty distribution itself, just open the ${jetty.home}/contexts/test.xml and look around. You'll see that it loads the ${jetty.home}/webapps/test.war via the ContextProvider's use of the ${jetty.home}/contexts/test.xml into the "/" context path.
Another note, look at the logs.
2012-01-13 13:56:28.779:INFO:oejsh.ContextHandler:started o.e.j.w.WebAppContext{/,file:/tmp/jetty-0.0.0.0-8080-test.war-_-any-/webapp/},/home/joakim/code/jetty/distros/jetty-distribution-7.6.0.RC3/webapps/test.war
That tells me that WebAppContext was
Started on {/, (the root Context Path)
Using the temp/work directory file:/tmp/jetty-0.0.0.0-8080-test.war-_-any-/webapp/
Using the web application specified in /home/joakim/code/jetty/distros/jetty-distribution-7.6.0.RC3/webapps/test.war.
Update: clarifying the statement about the empty context path.
See http://wiki.eclipse.org/Jetty/Howto/Deploy_Web_Applications:
If the webapp is called root.war or the directory is called root/ then
Jetty deploys it at the / context.
PS: I've never used Jetty, and it took me 3 seconds to find with Google.

Categories

Resources