问题
I have a project built and packaged with a specific version of jsp-apiand servlet-api jar files. Now I want these jars to be loaded when deploying the web project on any application server for example tomcat, WAS, Weblogic etc.
The behaviour I have seen on tomcat is that it gives messages that the packaged version of these apis are not loaded along with an offending class.
Is there any way I could override these server settings or behaviour?
My concern is that letting the default behaviour of a server may allow different behaviour on different servers or even on different versions of same app server.
回答1:
- If you have control over the server where you want to install this webapp you can replace the core jars with yours.
- Additionally you can prepend the jars in the startup of the app server.
Update:
As for the second part, you'll need to modify the startup file of the application server it self.
I don't have an installation at hand but lets suppose in the dir $YOUR_APPSERV/bin there are a bunch of scripts ( either .cmd or .sh files )
Some of them start the app server , some other help to configure it.
You need to modify one of those in such a way the command line look like this:
(assume a windows installation)
java -Xbootclasspath/p:c:\cutomjars\myJar.jar;customjars\myOtherJar.jar ..................... // the rest of the normal command line.
-bootclasspath/p prepends the jars to the app classpath
-bootclasspath/a appends the jars to the app claspath
This option let you override any class in the JVM with those specified in the jars, so you can even substitute java.lang.String if you want to.
That's one approach. Unfortunately -Xbootclasspath is an option for Sun JVM ( that is JRockit does not have it, nor the IBM's VM what ever his name is )
There was another option where you declare a folder where all the extensions are. Plus, there is an ext directory in the jre.
Take a deep dive into your application server bin directory and find out what each script is used for, I'm pretty sure you'll make it through.
Here's a more formal explanation of this topic: http://java.sun.com/j2se/1.5.0/docs/tooldocs/findingclasses.html
I hope it helps.
BTW, I use to do this years ago, to substitue the CORBA package with a veeeery old version. So this works for sure.
回答2:
I've split the answer in two for clarity
Tushu, I have two news for you.
The good one is I've managed to replace the servlet api from 2.5 to 2.3 in my tomcat using the steps I've described you in my previous post( screeshots below )
The bad new ( and I should've guessed this before ) The tomcat won't start.That's obvious, the servlet-api.jar is the core of the tomcat, and the version depends on some features present there. If it is changed, the engine won't work.
The solution I've show you, works to change the behavior of one or two classes, but not to substitute the whole system.
So , the only options you have are:
- Run on a servlet container that meets your servlet specification Upgrade your app
- Test it as it is on the new spec. Chances are ( and if you didn't link to non public classes ) your app still work
- ( I did this in the past ) create a new jar with exactly the classes needed ( let's say your app only needs one class to run well ) and then prepend that class to the container.
Here's the test jsp
Servlet version: <%=application.getMajorVersion()%>.<%=application.getMinorVersion()%>
Output with unmodified version:
unmodified version http://img89.imageshack.us/img89/9822/87694136ld9.png
Modified version:
modified version http://img241.imageshack.us/img241/7842/86370197ev3.png
Screenshot of the modified catalina startup
diff ouput http://img246.imageshack.us/img246/3333/30172332tp7.png
Tomcat stacktrace
SEVERE: Servlet.service() for servlet jsp threw exception
javax.servlet.ServletException: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:275)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
回答3:
JRockit can use -Xbootclasspath. See the command line reference
回答4:
Other option is to use
-Djava.endorsed.dirs
Upon JVM startup
来源:https://stackoverflow.com/questions/325171/overriding-application-server-behaviour-for-loading-jsp-api-and-servlet-api-jars