I want to extend the users admin portlet that is located in the control panel. I hooked the jsp and wanted to use methods from the service builder that are in the same hook as the jsp.
The problem is that the jsp can not find the classes. So I copied the *-service.jar to the tomcat lib/ext folder and removed it from the hook when deploying it.
But that doesn't work. After a while I get an exception that says Cache is not alive or this web application instance has been stopped already.
Is there a way to use methods from my custom service builder in the hooked jsp ?
The approach you have taken is correct, i.e. to put the *-service.jar inside [TOMCAT_HOME]/lib/ext and removing the jar from the hook.
The error might be because the hook may not have been properly undeployed, you may get some idea from this forum post. So my suggestion would be to:
Undeploy the hook
Stop the server
Copy the jar to [TOMCAT_HOME]/lib/ext
Clear temp and work directory
Restart the server
Deploy the hook
Whenever you remove a jar from a plugin-project and then just deploy without undeploying the portlet, sometimes you may notice that the jar file may be still present in the deployed webapps/plugin-project's directory, and this might be the case here as well. Also, whenever you put something in the global classpath (i.e. [TOMCAT_HOME]/lib/ext) you need to restart the server.
Also, don't forget to import the class in the JSP :-), just in case ...
Related
Basically I created some servlets on startup during the contextInitialized phase when my webapp starts up. But I need to be able to add servlets dynamically while the webapp is still running.
I'm starting to realize this may not be possible, so my next solution was to attempt to redeploy the webapp or restart tomcat. Is it possible to redeploy the app from inside the application? Or even add a servlet after the context has already been initialized?
At this point just being able to redeploy the .war would be enough.
As #JasonArmstrong says, you can trigger a reload using JMX Beans, which are available within the same JVM to any application. You can reload yourself or another application. I'll post code later on to show how to do that.
On the other hand, if all you want to do is deploy an additional servlet, you can do that using standard Java Servlet APIs.
The Java Servlet API ServletContext interface contains a method, addServlet, which allows you to deploy a new servlet. That, in combination with the return value from that method should allow you to deploy a new servlet after the application has been initialized.
For example (in a Servlet)
Servlet servlet = ...; // Make your servlet, here
ServletContext application = getServletContext();
ServletRegistration.Dynamic reg = application.addServlet("MyNewServlet", servlet);
reg.addMapping("/nyNewServlet");
UPDATE 2018-12-07
Apologies for the above text which has now been retracted. Everything about it is true except that you can't deploy new servlets (and, presumably, Filters and other things like that) after the context has been initialized.
== Back to original answer==
Or if you want to reload the context, you can still do it using JMX. The code looks something like this:
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
// Get the JVM's local "server" (there should be only one)
MBeanServer mbs = MBeanServerFactory.findMBeanServer(null).get(0);
// Create an "object name" that points to the application's
// context in Tomcat's MXBean tree. You might want to use
// jvisualvm or a similar MBean explorer to locate your
// application to get the exact right syntax for your context
// in the tree. Tomcat version may affect this value.
ObjectName objectName = new ObjectName("Catalina:j2eeType=WebModule,name=//localhost/contextname,J2EEApplication=none,J2EEServer=none");
// Invoke the "reload" method, which will
mbs.invoke(objectName, "reload", null, null);
The Manager app will allow you to update the application. You may also be able to do something with JMX MBeans.
The Manager app allows you to deploy and redeploy via update=true parameter. You can also start, stop, restart an app from there.
It’s not quite what you were looking for, but it’s pretty easy to set up.
I've made a trivial RESTful service on a JBoss server that just says "hello" when it receives any request. This part works and it is already deployed.
To go further with my project I need to log. The other applications on the server use log4j configured by a log4j.xml placed on a specific folder on the server.
For an offline project I'm used to have a runnable main method that in this case I would use to execute DOMConfigurator.configure(filepath) (where filepath is the log4j.xml) and I will be expecting to log with those settings.
However, since this is a deployed service (and since I'm not skilled enough to figure it myself) how would I so such a thing?
The question in my opinion could be interpreted in two ways:
How do I run some code "for sure" when I deploy something (in similar way to a main method) ? Do i need something like spring-boot?
How do I setup log4j on a deployed service on JBoss?
(I don't know if one question excludes the other...)
Thanks for the help!
1) If you want to run some code "for sure" you can create #PostConstruct method in one of your beans. Both Spring and EJB support it.
2)As for log4J configuration it should be enough to put it in classpath and add corresponding dependencies, no explicit configuration of path should be needed.
Not sure if it possible or not
Once a WebApp is running, is it possible to add a new JSP to the Webcontent folder, and assuming you know the name of newly added JSP make a requst for this new JSP?
Edit: Adding more details
We have a Java Batch application that will generate JSP files with embeded Java Scriplets e.g."<% Person.getName() %>". We want to be able to Run these JSP from within the web container to populate the javacode.
The only problem is that these JSP files are generated externally from the webapplication and we cannont restart the webapp everytime a new JSP is produced.
As a WebApp is running AFTER you deploy the project in the server, any change made while the WebApp is running won't affect the project until you deploy the project again.
I believe it's possible, but the question is too broad to give a meaningful answer.
One example of such behavior, is running Apache Tomcat server in debug mode in Eclipse, but that's a very special case.
I've made a web application using Java, Struts and running over Apache Server and Tomcat. It would be very useful to be able to restart the application from the web. I don't want to restart Tomcat, only this webapp, the same way as Tomcat Manager does it.
Do you know how can I do it? If not, any way to simulate that behaviour (reload config.properties, make Hibernate init process, etc)?
Thank you a lot.
I took a quick look at the source code for the Tomcat Manager. It looks like there's a class that's part of the Tomcat source called "Container Servlet". From the javadocs:
A ContainerServlet is a servlet
that has access to Catalina internal
functionality, and is loaded from the
Catalina class loader instead of the
web application class loader.
A ContainerServlet automatically gets passed a wrapper that can be used to get the Context and Deployer -- and the Deployer has helpful methods such as start(String contextPath) and stop(String contextPath) that will do what you want.
So, what I think you would need to do is write your own servlet that inherits from ContainerServlet, and configure Tomcat to load your servlet using the Catalina class loader (look at how the Manager is configured to see how). Note that this is probably not going to be an option for you in a hosted environment.
Then your servlet could have, say, a button you press to reload the application. I recommend putting password-protection of some kind in front of that. :)
Just hit the URLs
http://<username>:<password>#<hostname>:<port>/manager/stop?path=/<context path>
to stop and
http://<username>:<password>#<hostname>:<port>/manager/start?path=/<context path>
to start. That simulates you using the manager application.
Tomcat Manager offers an http interface to start/stop an application and other tasks. There are Ant tasks that you can use to easily access these operations.
I'm working on a project in Java using the spring framework, hibernate and tomcat.
Background:
I have a form page which takes data, validates, processes it and ultimately persists the data using hibernate. In processing the data I do some special command (model)
manipulation prior to persisting using hibernate.
Problem:
For some reason my onSubmit method is being called twice, the first time through things
are processed properly. However the second time through they are not; and the incorrect
information is being persisted.
I've also noticed that on other pages which are simply pulling information from the data
base and displaying on screen; Double requests are happening there too.
Is there something misconfigured, am I not using spring properly..any help on this would
be great!
Additional Information:
The app is still being developed. In testing the app I'm running into this problem. I'm using the app as I would expect it to be used (single clicks,valid data,etc...)
If you are testing in IE, make note that in some versions of IE it sometimes submits two requests. What browsers are you testing the app in?
There is the javascript issue, if an on click handler is associated with submit button and calls submit() and does not return false to cancel the event bubble.
Could be as simple as users clicking on a link twice, re-submitting a form while the server is still processing the first request, or hitting refresh on a POST-ed page.
Are you doing anything on the server side to account for duplicate requests such as these from your users?
This is a very common problem faced by someone who is starting off. And not very sure about the application eco-system.
To deploy a spring app, we build the war file.
Then we put it inside 'webapps' folder of tomcat.
Then we run the tomcat instance using terminal (I am presuming a linux system).
Now, we set up env in that terminal.
The problem arises when we set up our environment for the spring application where there can be more than one war files to be deployed.
Then we must cater to the fact that the env must be exclusive to a specific war file.
To achieve this, what we can do is create exclusive env files for every war. (e.g. war_1.sh,war_2.sh,.....,war_n.sh) and so on.
Now we can source that particular env file for which we have to deploy its corresponding war. This way we can segregate the multiple wars (applications) and their environment.