Hello all,
I'm on Tomcat 6.0.29 in Windows (XP or server 2003, same) and I'm trying to get
an application to deploy automatically without putting it in server.xml - as the
documentation strongly recommends.
Just to note, if I put the context setting in server.xml like this all works
fine.
<Host appBase="wtpwebapps" autoDeploy="false"
deployOnStartup="false"
name="localhost" unpackWARs="true" xmlNamespaceAware="false"
xmlValidation="false">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" pattern="common" prefix="access_log."
resolveHosts="false" suffix=".txt" />
<Context docBase="com.mycompany.myapp" path="/myapp"
reloadable="true" override="true">
<Manager pathname="" />
<Resource name="hibernate/MySessionFactory" auth="Container"
type="org.hibernate.SessionFactory"
factory="com.mycompany.myapp.HibernateSessionFactoryTomcatFactory"
configuration="hibernate.cfg.xml" />
</Context>
</Host>
If I remove the context from server.xml and place a context.xml in my app's
META-INF, then enable the two deploy params, the deployment happens succesfully
- that's what the console says at least. The application even starts ok, I can
see the logging of my classes.
BUT!
Each request to the application will throw immediately a HTTP error 400 - bad
request. Funny enough, this error will not even be logged anywhere, even when I
enabled debug logging in Tomcat! (and got 100M of logs which I searched
through). No record of the 400 whatsoever, while I can confirm the Host header
IS there - I see it in Firebug (and with the other context it works anyway).
What I see different is that the Tomcat's work directory, the
work/Catalina/localhost/com.mycomp.myapp directory it created automatically at
startup is and stays EMPTY. Now normally there should be the compiled JSP's
right? So there's SOMETHING not ok about this automatic deployment, and I'm
unable to figure out what it is. There was in May an interesting discussion
thread on this list called "Misunderstanding deployOnStartup actions", but that
guy also ended up using server.xml so... I only see advice like "your config is
wrong to start with", which might be very true (otherwise one wouldn't be
posting), but I wasn't able to see anywhere sampled a CORRECT config.
Thanks A LOT for any hints/samples/links,
JC
Short answer:
Please read (carefully), the following documentation:
http://tomcat.apache.org/tomcat-6.0-doc/appdev/deployment.html
Longer answer:
1. remove the docBase attribute from your Context
Your docBase would only work if you have a directory
$CATALINA_BASE/com.mycompany.myapp.
2. remove the path attribute from your Context
Rename your WAR file to myapp.war. Tomcat will correctly infer the path
3. Place myapp.war in $CATALINA_BASE/webapps
Tomcat (by default) will unpack and deploy your application
4. Remove the Manager node from your Context.
The Manager node relates to managing HTTP Sessions. The Hibernate sessions
relate to Hibernate units of work.
4a. Tomcat: http://tomcat.apache.org/tomcat-6.0-doc/config/manager.html
4b. Hibernate: http://community.jboss.org/wiki/sessionsandtransactions
5. Remove the Resource node from your Context.
6. Place the hibernate.cfg.xml file where it will be packaged in
WEB-INF/classes.
6a. In a NetBeans project, place it in <project-name>/src/java
6b. In a Maven project, place it in <project-name>/src/main/resources
7. Use a ServletContextListener to get a Hibernate SessionFactory.
Here's an example: http://community.jboss.org/wiki/UsingHibernatewithTomcat
I do things a little differently, by creating a utility class, and then using
that utility class in a listener. I can then attach logging and MBeans to the
listener.
. . . . just my two cent.
/mde/
First of all, thanks for your long answer.
Exactly from there I got the approach of "Copy unpacked directory hierarchy...".
It works actually, only gives the (expected) warning that it will be ignored.
But you're right, normally I removed it when switched to context.xml (didn't
mention in my message as I thought it unimportant)
I'm not using a war but the unpacked approach. Nevertheless, interesting - the
"automatic deployment" section doesn't mention this inference and I was always
wondering.
...and will it compile the JSPs as well? Because that was my original problem...
Yes but the Manager = "" should be used, according to Google, to avoid
serializing the HTTP sessions - a previously bothering situation. I think I'll
keep it :)
Hibernate.cfg.xml is there already... I'll try removing the Resource but I
remember needing to put it there as well (used in some filters) - I might be
wrong here.
I'll try this too.
No beans here :)
So, bottom line: great tips thank you! I will try them all. I'm honestly not
sure whether they relate to my problem, though...
JC
JSPs are only compiled upon first reference, not before. That results in slight (usually very slight) pause for the first guy in, so if you want t pre-compile them, there is a script available to do so:
http://tomcat.apache.org/tomcat-6.0-doc/jasper-howto.html#Pr[..] Coniguration
- Chuck
THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MTERIAL and is thus for use only by the intended recipient. If you receivedthis in error, please contact the sender and delete the e-mail and its attchments from all computers.
Interesting, thank you. I will look into this.
I would have still expected that in the automatic deployment with the single
context.xml, tomcat still does that. For the first user, with delay, no problem.
But it threw an unlogged error 400 and didn't compile zit, thus my original
problem stays...
Thanks a lot,
JC
Just curious: why wtpwebapps? Eclipse IDE uses that name.
Try with recent 6.0.x (build it yourself), or 6.0.30 (when it comes
out), or 7.0.5 -- they will log such requests into AccessLog.
Usually it means that this request was rejected by the connector, or
by CoyoteAdapter. What is your client?
Do you have a ROOT application deployed? You should have one.
Best regards,
Konstantin Kolinko
Precisely :) Only because Eclipse publishes it there, so the name was kept. No
other reason.
Ummm, I wouldn't go into beta stuff... I have enough troubles as you can see :)
and what do you mean by "client"? The browser?
This is true, I don't have one. Might this be The/a problem?
Thanks a lot,
JC
If the request isn't being routed to your application, then without a
ROOT application the host hasn't got a mechanism to serve any response
other than an error.
p
This is either because your application is not deployed, or because the
request path you're using does not match the actual request path deployed.
When you start Tomcat, is there a message in the logs saying:
02-Dec-2010 10:44:17 org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory com.mycompany.myapp
OR
02-Dec-2010 10:44:17 org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory myapp
?
What is the exact URL (you may omit the actual domain if you wish) that
you then request?
p
Hmmm, it says "Deploying web application directory com.mycompany.myapp" which
is somehow what I was expecting (it IS in that directory under wtpwebapps), then
I'm calling it with http://localhost:8080/myapp (I need it that way)
Now that you mention, I notice this difference:
- when I put it in the server.xml and it gets deployed automatically, Tomcat
creates under "work/Catalina/localhost" the directory myapp. All fine.
- when I use the standalone context.xml it creates under
"work/Catalina/localhost" a directory com.mycompany.myapp - which stays empty
afterwards.
I still don't know what and why it happens, but I feel it's getting closer to
the root cause :)
Thank you,
JC
Error is fine, as long it's a 404 (and not this enigmatic 400)...
Thank you,
JC
When you say "standalone context.xml", are you referring to a <Context> elment located in the webapp's META-INF/context.xml directory?
Make sure you don't have a conf/Catalina/[host]/[appName].xml file, since hat will override anything inside the webapp.
Please post the entire (not just a fragment) server.xml you're using with he "standalone" context.xml, along with the <Context> element. Remove allcomments and obfuscate proprietary information first.
- Chuck
THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MTERIAL and is thus for use only by the intended recipient. If you receivedthis in error, please contact the sender and delete the e-mail and its attchments from all computers.
Yes, that one.
It usually gets created automatically, right? I remove it by hand each time
before I plan some changes/redeploy.
Here it goes:
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener SSLEngine="on"
className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener
className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener
className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Service name="Catalina">
<Connector URIEncoding="UTF-8" connectionTimeout="20000"
port="8080" protocol="HTTP/1.1" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine defaultHost="localhost" name="Catalina">
<Host appBase="wtpwebapps" autoDeploy="true"
name="localhost" unpackWARs="true" xmlNamespaceAware="false"
xmlValidation="false">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" pattern="common" prefix="access_log."
resolveHosts="false" suffix=".txt" />
</Host>
</Engine>
</Service>
</Server>
Thank you,
JC
The app is under /com.mycompany.myapp not /myapp.
That's the problem, Tomcat is then trying to find an app to serve that
URL, can't so sends 400.
Because you can specify the path in server.xml.
Otherwise it's dependant on the app directory/war file name, unless you
do some trickery with the conf/Catalina/localhost/myapp.xml file.
Easy solution: rename the dir from "com.mycompany.myapp" to "myapp".
WAR files are not packages, give them a sensible name.
p
400 isn't enigmatic and /is/ an error. ;)
You can either implement a custom ErrorValve in your host, or provide a
ROOT application. Any request to your server that doesn't match the
path of a deployed application gets directed to ROOT. Which you don't have.
I'd suggest you make a simple empty ROOT app. Tomcat will then serve
404s for missing URLs. You could also customise the 404 response page
to suit.
p
It IS an error indeed, but we're not talking about throwing just ANY random
error number here :)
400 is a specific error which to my untrained eye has absolutely nothing to do
with the fact that under the named context there's no application deployed.
That's why a 404 would have sent me much sooner in the right direction -
resource not found, instead of trying endlessly to play with the request headers
and the HTTP protocol details. But maybe it's just me.
Yeah I probably will do that - but I will still regard it as a dirty hack...
Otherwise thanks a lot for your support, I was obviously misunderstanding what
the Path parameter of the Context is expected to do. Now I know what I have to
change. Or I think so at least. Back to the drawing board.
Thanks a lot to you all gals/guys,
JC
A ROOT app should be mandatory.
p
It's not - yet :) so I'm all legal without. But what do you think about the 400
error? Is it really appropriate as answer in this setup? And is it really my
particular need to write an application only to convert the 400 into 404? I'm
just surprised...
...or maybe I should consider whether my application can be both root AND answer
to the context...
Cheers,
JC
Really, you *must* have a default webapp. Why don't you just deploy your ebapp as ROOT and be done with it? Don't make life difficult for yourself.
- Chuck
THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MTERIAL and is thus for use only by the intended recipient. If you receivedthis in error, please contact the sender and delete the e-mail and its attchments from all computers.
02.12.2010 20:44, Pid:
Yes, it is an error. But in this case, I, too, consider the error erroneous.
A status code of 400 basically means that the request was syntactically
b0rked. But, as I understand it, that's not the problem here: the
request is syntactically fine - it fails because the server is
misconfigured. Therefore a status code of 500 seems more appropriate to me.
--
Regards
mks
> From: Markus Schönhaber <tomcat-users*******says:=0A=0A"Error 4xx, 5xx =0AThe 4xx codes are intende for cases in which the client seems to have erred, =0Aand the 5xx codes fr the cases in which the server is aware that the server has =0Aerred. It s impossible to distinguish these cases in general, so the difference =0Ai only informational. =0A=0AThe body section may contain a document describng the error in human readable =0Aform.=0A=0ANot found 404: The server hasnot found anything matching the URI given =0AInternal Error 500: The serve encountered an unexpected condition which =0Aprevented it from fulfillingthe request."=0A=0A=0AI still vote for 404 :) (as if my vote matters) becase the server is all fine =0Aand dandy (the APP is misconfigured not the srver), but the client is asking =0Afor something not available. But the diference is only informational :)=0A=0ACheers,=0AJC=0A=0A=0A
Well, 404 might be appropriate from the client's point of view.
I think I remember the recent suggestion of a default ROOT application,
used when no other is present, which would prevent this from actually
being a problem, it seems like a good idea to me.
p