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?
Related
I am working on SAML SSO Authentication.
I have created a servlet to generate SAML metadata and i deployed it and run it and I got the output.
Same time I have created a java class to generate SAML Metadata with the same code and tried to run it independently. I have added the same Jar files that I have used for that servlet application.
But I got the Exception given below. Can anybody help me to find the difference between running an application independently and by using java servlet??
Thanks in advance.
Exception:
Running as servlet in a web container means all sorts of stuff is on the classpath that is automatically provided by the servlet container.
Running using main() means you have to put all needed stuff on the classpath yourself. The ClassNotFoundException you got should be clear enough in that respect.
(Pls note that although I did say "the" classpath, in a servlet container things are typically not quite that simple. But that's not the point. Also note that running as a servlet, and using features of libraries provided for the container, may even mean your stuff cannot run as an independent java program simply because the library stuff was deliberately intended for servlet container use exclusively.)
We have been using tomcat 7.0.19 successfully in embedded mode. However recently due to some fixes in our area of concern we decided to move to tomcat 7.0.32. Most things work as expected with same code and newer version, however the war deployment for some reason has'nt worked well. I have a couple of servlets registered with my tomcat. Facing below 2 issues,
Has something changed from 7.0.19 to 7.0.32 from embedded tomcat behavior. To detail this out let me explain the behavior difference, with 7.0.19, i could deploy my application and when i hit the "host:port/contextpath" it loaded the applications start page (i.e. welcome page, this page is UI centric and does not need a server intervention, so none of my servlets get called). However with 7.0.32 the same url results in my servlet being called.
So to debug the problem, i commented most of my code so that i have a vanilla tomcat implementation, just the very basic stuff, i.e. setting the engine name, default host, setting host properties, adding a connector (nio, with default properties) and deploying a war. No servlets and other things, just to check if the very basic stuff works. To my surprise when i ran this code it still failed with the same problem within my servlet, how did that happen, now that my code is commented it does not register any servlets, still where does it find it from? Does embedded tomcat store some old references, which are not getting cleaned on subsequent runs? I tried changing the port, but that too didn't help.
I am hitting the wall here, not able to understand this wierd behavior, if i figure out #2, only then can i make some progress on #1.
Thanks in advance,
Vikram
Figured out what the problems were.
In reverse order,
2 - This actually was a weird behavior with the vanilla embedded tomcat code too invoking the servlets which never were registered in the first place. The problem here was with eclipse, for some reason it picked up the old reference of my class. The moment i ran the same code from outside of eclipse i.e. via command prompt, things were back to normal.
1 - This problem was related to web deployment, in my code i was additionally setting my classloader into WebappLoader and eventually adding my application jars into it. This for whatever reasons worked fine with 7.0.19, however did not with 7.0.32, the moment i externalized all my jars to be loaded during application startup via classpath this problem too was resolved.
Thanks,
Vicky
I have a third party application which has lot of servlets and jsp. I wanted to debug that by putting breakpoints on my local jboss server. How do I know that, for a particular request, the request is being processed by particular java classes and jsp, so that I can put breakpoints in the right files? I am thinking of going through the code, before setting the breakpoints, to know where to put them. But I feel this is not an efficient way to do it (as it is a very big application). Can you please suggest if there is any better way to do this?
Thanks in advance.
The web.xml file contains servlet-mapping elements indicating which servlets are mapped to which URLs. So if you know the URL, you should easily find the corresponding servlet. Now you can read the servlet code to see which other classes are involved.
I think fastest way for debugging applications like this, is profiling application for specific usecase, in this way you can understand which classes used for this scenario and after finding classes, you can debug these classes.
for profiling application there are lots of tools.
commercial: Yourkit, JProfiler, JProbe
open source:VisualVM, Javacalltracer (create run-time sequence diagram)
This question already has an answer here:
Using special auto start servlet to initialize on startup and share application data
(1 answer)
Closed 7 years ago.
We have a few war files deployed inside an ear file. Some of the war files have a class that caches static data from our PLM system in singletons. Since some of the classes take several minutes to load we use the load-on-startup in the web.xml to load them ahead of time. This all works fine until we attempt to re-deploy the application on our production servers. (WebLogic 10.3) We get an exception from our PLM API about a dll already being loaded. Our PLM vendor has confirmed that this is a problem and stated that they don't support using the load-on-startup. This is also a huge problem on our development boxes where we have redeploy the app all the time. Most of us, when we're not working on one of the apps that uses a cache, have them commented out. Obviously we can't do that for the production servers. Right now we transfer the ear to the production server, deploy it in the console, wait for it to crash, shut the app server instance down and then start it up again.
We need to find a way around this...
One suggestion was to create a servlet that we can call after the server boots that will load the various caches. While this will work I'm looking for something a bit cleaner. Is there anyway to detect once the server started and then fire off the methods?
Thanks.
We had a similar problem with a third party JDBC driver that loaded a native DLL. When redeploying the app the driver would crash saying the DLL was already loaded. The solution (if one can call it that) was to move the driver from deploy into lib. This way the driver was global to the app server and didn't need to be reloaded when the app was redeployed.
What about using a servlet container lifecycle listener, such as ServletContextListener?
Example on how to use.
EDIT: Sorry, after re-reading your question I don't think this will work. You want something that will load only once per server life, not application life. The ServletContextListener's methods will be called each time the app is deployed, just like a load-on-startup servlet (which it seems you are using). My suggestion will do the exact same thing in a different way.
I would try Chris Nava's suggestion.
EDIT2: It looks like tomcat has some lifecycle listener(s) available to it also. It looks like documentation is sparse, but this potentially would allow you to do something on server startup specifically only once.
EDIT3: Yes, a tomcat lifecycle listener is the way to go. This link explains pretty well how to set one up. Should be fairly straight forward. If you ignore the part about adding the Transaction to tomcat, it goes over pretty thoroughly how to add a lifecycle listener.
I have a small test class that I want to run on a particular jvm that's already up and running (basically it's an web application running on Tomcat) . The reason I want to do this is I want to execute a small test class (with the main method and all) within that jvm so that I get the same environment (loaded and initialized classes) for my test class.
Is it possible to indicate that ,say through a jvm parameter, that it should not initialize a new vm to execute my class but instead go and execute on the remote vm and show me the result here, on my console. So the local jvm acts as a kind of thin proxy ?
I am not aware in case there are some tools that should make this possible .Also heard somewhere that java 6 jvm comes with an option like this , is that true ?
Please help me.
Thanks,
After reading this question and the answers, I decided to roll my own little utility: remoteJunit
It is lightweight and dynamically loads classes from the client to the server JVM. It uses HTTP for communication.
You might want to take a look at btrace. It allows you to run code in an already started JVM provided you don't change the state of the variables inside that JVM. With this kind of tracing, you might be able solve your problem in a different way. Not by running extra code in form of a new class but by adding safe code to and existing class running inside a JVM.
For instance, you might System.out.println the name of the file when there is a call to File.exists.
You might find JMX useful. Register an MBean in the server process. Invoke it with visualvm (or jconsole). (tutorial) Never tried it myself, mind.
RMI would also do the magic.
http://java.sun.com/javase/6/docs/technotes/guides/rmi/index.html
Make your web application start an RMI registry and register your service
beans there.
Then in other JVM you can run a program that queries the RMI registry
started by your web application for the services you want to verify
and you are done.
I assume "small test class" is basically some debugging code you want to run to monitor your real application, which is deployed remotely on a Tomcat. If this is the case, you should connect your Eclipse debugger remotely to the Tomcat instance, so you can set a breakpoint at interesting locations and then use the Display view of Eclipse to run any arbitrary code you might need to perform advanced debugging code. As java supports Hot Code Replacement using the debug mechanism, you can also change existing code on the remote side with new code at runtime.