We are developing a webapp using WebLogic 10.3.4. our UI team is experiencing pain with the slow turnaround times between a JSP edit and seeing the results in their browser. Things are a lot easier with Tomcat 7.0 but this uses a different JSP compiler from the one we are targetting.
My question is, is it possible to swap out the default compiler in Tomcat and replace with the one from WebLogic? If so, how would I do this? We know that the WebLogic compiler can be called from the command line (we have it in our build). It looked like you could do this with the IBM Jikes compiler in the past, but I can't find any mention of WebLogic.
--- Edited as question changed slightly ---
You cannot easily swap out the Tomcat JSP compiler for another JSP compiler, as the Tomcat JSP compiler is integrated into Tomcat. While all JSP compilers function in a similar manner, the cost of reworking the integration of one system with another compiler is the reason such a swap is not easily performed. Most web containers do not call these compilers out-of-process, but rather they launch them on dedicated threads in the web container.
That said, perhaps you can avoid compilation in the web container alltogether. If you pre-compile your JSP pages with either the Tomcat or the Weblogic JSP compiler, then you can simply package the previous JSP pages into the WAR as .class files, and when the time comes for the first-access of the previously mentioned JSP file, the web container will not have to pause an additional amount above class access time to compile the JSP into a .class file.
JSP compilers are very much like regular Java compilers, with the main exception being that they take JSP files as "source code" instead of .java files. Once you work out the arguments, CLASSPATH, and parameters for your JSP compiler, you can integrate it into your build chain just like you do your regular .java files.
Details on precompiling with Tomcat's JSP compiler.
Some information on precompiling with Weblogic's JSP compiler.
--- Original Post follows ---
Yes, it is possible; provided that the compilers for both support the same release of java, and are configured to compile to the same release of Java.
Related
I have started using tomcat 7 for few days. I have tried executing many JAVA BASED web application with it. I actually want to check the flow of the java based web applications. That means in which sequence the methods of web application get executed. To do this I profile tomcat server with java profiler.
My profiler works like this:
I deploy war file of an application into web Apps dir of tomcat.
I start the server by ./startup.sh
I access the application in browser and execute it.
I stop the server by ./shutdown.sh.
and after I stop the server, the profiler dumps the output in xml format(it shows heirarchy of methods as calling context tree).(MY profiler basically profiles methods of java classes.)
As you know, may be because Tomcat is based on servlet, for 2 exactly same runs of an application(I follow above 4 steps 2 times and have 2 different output for 2 same runs), profiler gives different outputs. Q.1) I dont exactly know why this happens would be very curious to know the reason behind it.
Also the output is very large (around 200 MB) even for simple application. To limit the size of the output and to have same outputs for 2 exactly same runs, I have excluded methods of org.apache.* from profiling. Because I am ultimately interested in knowing the flow of the web application itself.(to know in which sequence methods of web application get executed). For this scenario I have following questions.
Q.2) Running application by deploying war file and running it by fetching it form the directory itself can make difference in the output of the profiler ? or can it affect a sequence of methods in which they execute in both the cases ?
Q.3) I would like to know what happens when I execute jsp page of an application ? I mean how does tomcat execute them? step wise please....
Q.4) when I check the output of the profiler after executing an application, I see large no of methods from org/eclipse/jdt/internal/... get executed. So what do this classes do actually ? Why do I have them in my output ?
Please let me know if I have failed to explain my questions. I kiind of searched a lot but could not find very precise answers to my questions.
I would really appreciate your responses..
Thanks you.
I strongly recommend to read a bit about tomcat works. In short
Q.2 Shouldn't make any difference.
Q.3 JSPs are compiled to servlet classes when they get called. If there is no Servlet class for the JSP tomcat makes one. If there is a corresponding servlet class, tomcat looks which one is younger, the JSP or the servlet. If the JSP is younger it does a new compilation, if not it uses the servlet.
Q.1 Not sure. Could be a multithreading/timing thing, Maybe it's the way your profiler works.
Q.4 Not sure. Could a be classes from the profiler or libraries used by your servlet code?
EDIT: For Q.4 look at Ian Roberts' comment to the question.
What profiler do you use? How about going stepwise through the code by debugging it?
I have been using JSP,Servlet for quite sometime. I know that whenever we change anything in Servlet we need to restart Tomcat Server to get the changes. Where as in case of JSP change, tomcat does not require restart.
As per my knowledge JSP page gets converted into Servlet only when compiled. So, after all its a Servlet.So, How does it works without Tomcat restart.
I have knowledge of cases when a JSP page gets compiled like on first time access after server restart etc.
Because when Tomcat is asked to execute a JSP, is compares the modification date of the JSP file with the modification time of the compiled class corresponding to this JSP, and if more recent, it recompiles on the fly before executing it.
This is BTW an option that should be turned off in production, because it takes time to perform this check.
See http://tomcat.apache.org/tomcat-7.0-doc/jasper-howto.html for details.
Because by default tomcat is started in development mode, which means JSP-derived servlets recompiled when a change is detected. It's a good questions how does the JVM load the new class - probably the tomcat classloader is configured to do so.
A few related notes:
you can turn off the development option for production
you can have servlets been reloaded as well - you have to start tomcat with a JVM in debug mode.
Not just JSP's some containers also support reloading of servlet class if it is modified.
It is upto the container to decide when to load servlets. A servlet can be loaded at runtime on demand. And coming to JSP, JSP translated to servlet can also be loaded at runtime.
Coming to your question,
Why Tomcat does not require restart?
It is because Tomcat is capable of adding/modifying classpath to Web Application classloader at runtime. Tomcat will be having their custom Classloader implementation which allows them to add the classpaths at runtime.
How does the custom classloader might work?
One way to get this working is when a Servlet/JSP is modified, a new classloader is created for the Servlet/JSP with Application classloader as parent classloader . And the new classloader will load the modified class again.
I want to build a java web application and I don't have any background how to do that.
Can you plz tell me what is the starting point to do that and where can I found useful open source codes that I can use them to design my web application.
There are many different frameworks and without more information it's difficult to know what would suit you.
http://en.wikipedia.org/wiki/Comparison_of_web_application_frameworks#Java is a good starting point.
You have to know concepts such as Servlet, Servlet Container, Application Server(such as Apache tomcat) and little information about Html.
Exist several book for this goal, my opinion is : you start by a book related to Jsp/Servlet concept, these books good explained.
Here you can learn how java web applications work and here is a very basic java web application example to get you started. I hope this helps :)
You should follow the Java EE tutorial, its Web Tier part. I think it's the fastest way to get knowledge that would allow you to understand the base concepts...
The minimal structure of a web application is the following:
/WEB-INF
/classes - stores the compiled Java classes your webapp uses
/lib - contains the additional libraries your webapp may need to run
web.xml - key file in every webapp; explained below
web files and folders (HTML/JSP/CSS/Javascript)
You may want to start out with Eclipse for Java-EE, since it automatically creates the webapp structure for you, so it's the perfect place to start learning, in my opinion; you can find it here.
After you install, the basic steps to create your web application are:
Create your project by accessing File > New > Dynamic Web Project.
Name your project, click Next, Next and check the Generate deployment descriptor checkbox. Now hit Finish.
Now that the structure is created, your main points of interest will be:
Deployment Descriptor - Is an overview of your web.xml file. Here you can declare all your servlets and their URL paths, you can point to specific error pages triggered by specific codes (e.g 404, 500) or exceptions that occur in your Java/JSP code (e.g NullPointerException, FileNotFoundException), plus do many other things to enhance your webapp. You can trigger between text and graphical XML editing in the bottom-left of the code window.
Java Resources - Here you define your Java classes and servlets. The main role of a Java class in a webapp will be to collect and process data. For example you can define your own math class that exposes methods which do basic calculations. A servlet will usually call one of these classes and output the result to the response output stream. Be sure to provide a solid project structure with the help of packages.
WebContent - this will contain all the web pages your webapp will show, including scripts, images and stylesheets. You are free to create your own folder structure in this section.
Some useful tutorials to get you started:
HTML
JSP
Servlets, Server setup
CSS
Once you're done with your webapp, you can either Run it on a server directly from Eclipse, or you can export it as a WAR file and deploy it on the server of choice, which is usually done by copying the WAR file in the webapps folder.
Finally, try to experiment with all the webapp features Eclipse exposes to you. Good luck!
I have two questions regarding Java web application deployment and its impact on performance.
We have an application deployed on serverA, with JSPs exploded in to one content directory (that means JSPs are not part of the WAR)
question 1: What I knew was this was an approach for development rather than any other environments. Does this exploded deployment slow down performance?
now, the content directory is cross mounted(NFS share) to another hardware, and there we run serverB, which also use the JSPs for its content.
When both serverA and serverB are running and utilizing the same content, can it slow down the performance?
Deploying JSPs in exploded form (rather than in a WAR file) won't make any difference from a performance perspective. When a WAR file is deployed, it is unpacked anyway.
Putting content (including JSPs) in an NFS mounted file system will make access to the files, and can lead to operational issues if your NFS mounts go stale at the wrong time. This will happen the first time a JSP is used, and can also happen at other times if your JSP engine is configured to periodically check for changed JSPs.
The first time any jsp is needed, it would be compiled into a servlet and stored in the web container's cache(at-least tomcat does it). Since the cache folder is not over NFS, that shouldn't affect web sevrer performance. It might be a good idea to precompile your JSPs though.
Exploding the WAR should slightly improve deploy time, but the server is going to explode the WAR file anyways when it's deployed.
As other replies pointed out, JSPs are translated into servlets and then compiled into .class bytecodes. This happens the first time a user accesses that JSP, and this will produce lag-time for the users, especially if it's a complex page. The best way around this is to precompile the JSPs.
If you application's JSPs are precompile and the compiliation feature is closed in Servlet container, it does not impacts your application's performance,because the JSPs were compiled to their .class file,and then they would be loaded by container.
I hit on this nasty behavior on JBoss 4.2 in QA, and I want to nip it in the bud before we go into production and find some other corner case.
A jsp calles a method that had the following signature:
public void methodName(String arg)
This was changed to:
public void methodName(String arg, Object... args)
A pre-existing JSP called this method via:
methodName("param");
On deployment of the modified code, JBoss did not recompile the JSP and this caused a crash in QA. Adding a silly comment to the jsp fixed the problem (JBoss recognized that the JSP changed and recompiled it).
Is there a setting on JBoss to force recompilation of JSPs on restart?
EDIT: To clarify some points in the answer, the setup is that the JSPs are part of a war which is part of an ear. The ear has all classes in it, in a jar.
Regarding the desire to pre-compile, if the system doesn't think that the jsp needs compilation, will pre-compile force recompilation? It doesn't seem so. The error here is not a compliation error, it is a method invocation error because of the "changed" (at the byte code level, not really at the code level) method signature.
Addendum: Note that we experienced in production recently that even with the accepted answer's flag set the JSPs did not recompile, even though the JSP did in fact change. Major bug there, but regardless, JBoss was shutdown normally. At this point it is getting to be an old version of JBoss, but if you are still using it, deleting the content of the work and tmp directories is the only way to be sure.
I'm not changing the accepted answer simply because it really gets to the point of what the question was looking for. JBoss bugs are kind of a separate issue.
If the JSPs are part of a WAR that is part of an EAR that is being deployed as a jar, then I'm not clear why your JSPs are not being recompiled. Don't the JSPs in the war file have newer timestamps than their JBoss-compiled class files from the last deploy? If not, couldn't you touch the JSPs as part of building the WAR/EAR before deploying. [I'm referring to using the Unix "touch" command, not manually touching each JSP file.]
Alternatively, the DeleteWorkDirOnContextDestroy setting in $JBOSS/server/default/deploy/jboss-web.deployer/META-INF/jboss-service.xml may be what you are looking for. It is false by default, but setting it to true may be what you need. I think this should delete the JSPs' class files on redeploy so that they get recreated upon first access of each JSP.
See https://jira.jboss.org/jira/browse/JBAS-3358 for more info.
I don't know of a setting, but deleting the generated Java class file in the work directory of your JBoss instance will cause the JSP to be recompiled the next time it is called.
You coudl alter the JBoss startup scripts to explicitly delete the "tmp" and/or "work" directories, where the compiled JSPs are stored. JBoss would then have no choice but to recompile them all.
Not subtle, but it would do the job.
One option for you would be to precompile all of your jsp's at build time. This would quickly flag any compilation errors.
You could also do this in production - speeding up first access but I get the feeling you want this more for a QA step than anything else. If so, you could add the precompile step to the your testing phase in your build tool of choice - and so to your CI environment. This would provide assurance that jsp's that don't compile won't make it out of test.
See this for details on running a precompile task:
Jboss Jasper configuration
Hope this helps.
Some JSP containers (as per section 8.4.2 of the JSP 1.2 specification) support the capability of precompiling a JSP page.
To precompile a JSP page, access the page with a query string of ?jsp_precompile
http://hostname.com/mywebapp/mypage.jsp?jsp_precompile
The JSP page will not be executed. If the container supports precompilation, the JSP page will be compiled if necessary.
See also http://www.rgagnon.com/javadetails/java-0414.html
Pablojim is on the right track. You just need some more info to get a complete view of what's going on. Here's how I understand it.
In prod, you've changed a jsp that requires other jsps to be recompiled. In order for them to be recompiled one of 2 things must happen
The compiled version of the jsp needs to be deleted.
The jsp itself needs to be modified (or even if it's "touched" - modified date is updated)
If you still need to verify that all your jsps work, they will all need to be precompiled using an ant task. this also allows you to deploy the war file with the precompiled jsps in the war file. This should solve your problem.
If your files are not deployed in a war file, but in an exploded format, you should seriously consider packaging your web app in a war file for deployment. This makes it a nice package to deploy between environments.