Vaadin Entry Point - java

I am wondering if/where I can put some code to run the VERY first time the Vaadin server is initialized? (Not the first time a user hits the site)
(For example for loading proxy settings from files, starting rss crawlers etc.)
It's quite possible I'm missing a trick with the JavaEE stuff here, I'm pretty new to this stuff.

Use ServletContextListeners. It's an interface whose contextInitialized method is called everytime the server is started. They are really simple to use, just implement the interface and add your context listener to the web-xml, see this example.

Another way would be to extend ApplicationServlet and override the init() method.
Then you have to modify your .xml file to point to this servlet instead of Vaadin's default one.
This method is called once the servlet is brought up by the container.

Related

How to dynamically add and remove servlets within a servlet context in Jetty 9.4.x?

I would like to add and remove servlets within a servlet context dynamically. I know how to add multiple servlet contexts dynamically using a ContextHandlerCollection. However, I need to do the same with multiple servlets within a context. Is it possible to add further servlets, once a servlet context is started?
Servlets can only be added, not removed.
See the various ServletContext.addServlet() methods.
Note, however, that you can only change the ServletContext during ServletContextListener.contextInitialized() (see javadoc in ServletContext.addServlet() for the UnsupportedOperationException throwable)
I did implement it several years ago in an ECM component so servlets could be added and removed via ConfigAdmin settings without restarting Jetty itself in an OSGi environment.
As it was more than two years ago, I do not remember every detail, but you can check the code yourself. See the updateServletsAndFilters() function of CustomServletHandler class here: https://github.com/everit-org/jetty-server-ecm/blob/master/component/src/main/java/org/everit/jetty/server/ecm/internal/CustomServletHandler.java#L88
Some hints:
In the CustomServletHandler subclass, I set a flag ignoreUpdateMapping while I update all mappings again otherwise the parent class would calculate the complete mapping after each iteration applying the new Servlet array
I use _ReadWriteLock_s so during the update the ServletHandler will hold the new requests until the remapping is done
The function above is called from updateServletHandlerWithDynamicSettings() function of ServletContextHandlerFactoryComponent class (this is where the mappings, servlets and filters are precollected based on configuration): https://github.com/everit-org/jetty-server-ecm/blob/master/component/src/main/java/org/everit/jetty/server/ecm/internal/ServletContextHandlerFactoryComponent.java#L86

Converting WebApp into Desktop Application [Java]

I've been writing this very easy Webapp. It receives two parameters, a word and a letter. It counts how many times the letter can be found in said word.
I have a Dynamic Web Project in Eclipse with the following:
OccurencesCounter.java : has the method count with two params: word and letter. it returns the count (amount of times letter found)
OccurencesServlet.java In here I create an OccurencesCounter obj, I get the params, I call the function count etc, and I forwards request/response to result.jsp
result.jsp I show the results I've calculated.
This has been done for an exercice on Parameters and MVC.
According to the MVC pattern, I can change this webapp easily in a desktop application.
I know i need to change my view, result.jsp.
I need a main class. The rest of the code should stay the same.
My question is the following: What do I use the servlet for? I can't fathom how I could still need it.
I think I can use JOptionPane to input my parameters ("HelloWorld" , "o"), but bypass the servlet alltogether. I'd just need the OccurencesCounter class and my main class.
Is this normal? Or should I use the servlet (in some unknown way to me).
I'm confused, as this is an assignment telling me: We only want you to adjust the view when you create a desktop application, as it is requested by the MVC pattern. Make sure you have one model that works for both assignments.
Thank you
A Servlet listens to http requests and executes Java code, if the requests url matches the servlet mapping. This is useful when working with HTTP (server side/web application) but not in a desktop application (event driven).
We only want you to adjust the view (not your class) when you create a desktop
application, as it is requested by the MVC pattern.
They want you to reuse your OccurencesCounter class in both environments. Thats always possible, if that class does not include any kind of technique, related to the environment, for example a Servlet.
Make sure you have one model that works for both assignments.
Actually, you class is not a "model", from MVCs point of view. Its more of a service, that can be called (delegation) by a controller, returning the result (model) and displaying it on any kind of view.
So just create a class with a main method and run your OccurencesCounter class from there.
If you followed the MVC pattern in you web application you should have :
Model : a set of service, dao, and business classes that will be reused in the desktop application
Controller : a set of servlet (or controllers if you used a framework) -> al that is UI related and have to be rewritten
View : a set of HTML, JSP, CSS, etc. -> must be rewritten
The MVC model allows to (almost) easily replace the view part, if you want to migrate from JSP to Velocity or Thymeleaf but still in a web application

With Tomcat 5.5, how can I programmatically locate a specific servlet instance or add new mappings?

I understand that this is normally not done, and I've found a number of instances of this question around the web with answers of the sort: "Your design is wrong if you need to do this." Let me explain my goal.
I have a web app that at one site somehow caused one servlet's init() method to be called repeatedly. I don't know how this happened and I cannot repeat it. However, from a binary heap dump (caused by an out-of-memory exception), it is very clear from objects on the heap that a specific servlet's init() method got called about 10,000 times, as that is the only place these objects are created and there were 10,000+ instances of an object that is supposed to have no more than one instance.
Since I cannot reproduce what happened at this one site, I instead want to forcefully invoke init() many times on this servlet, preferably via a JSP file, so I can test before and after a fix is applied. Testing the "after" case is easy in theory because I can change the code to (for example) stick this servlet into the context so I can get it and repeatedly call init() to prove that there is no leak of this object. But this does not help me test the "before" case with the existing code.
I cannot just "(new MyServlet()).init()" in a JSP. This fails as the servlet is created with a null context and fails to initialize. By Tomcat 5.5, it seems that ServletContext.getServlets() always returns an empty Enumeration and that ServletContext.getServlet(String) always returns null.
It seems the easiest way to test is if I can somehow programmatically (preferably from a JSP) get access to the servlet instance in question, or alternately, programmatically add new mappings to that same servlet class, which might create new instances. (?)
You've already figured out that what you are attempting is highly out of the ordinary and far from a best practice so I won't go into any detail on that subject. Having said that, if you want to invoke MyServlet.init() many times on an instance of MyServlet running within Tomcat, you could subclass MyServlet, override the doGet() or doPost() method, add a loop that simply calls this.init(); 1000 times and then call the parent classes doGet()/doPost(). Edit WEB-INF/web.xml to use your subclass in place of MyServlet. Then just hit the servlet with your web browser and see init() called 1000 times prior to serving the page normally. And you haven't modified the original MyServlet class at all, keeping your before test pure.
You can create a servlet instance like any other class object. Get hold of the servlet config by overriding the method init(ServletConfig config). And create the servlet class instance as many as u want, and call init(ServletConfig config) on all those instances created.

java servlets init and destroy

servlets uses init() to initialize servlets status and destroy to clean up. Is there a special class name we need to put init() and destroy()? How does servlets know where to find these methods?
asp.net has a global.asax to handle similar thing in asp.net , servlets has a special class to do the same thing?
Thanks
Servlets will ultimately be a subclass of the javax.servlet.Servlet class, which defines those methods.
It should be in the same class as your Servlet class.
All servlets inherit this method from the base Servlet class. Unless you want to do some additional processing, the inherited method should be fine and you dont need to override this method in each of your servlets.
Servlets are deployed in the Container(Web Server/Application Server),That container will take care of initializing or destroying of servlets,and we dont have predefined classes to initialise and destroy for servlets,if we use particular class that means we are depending on that class(Tightly Coupling) thats not recomended.
Now we are using GenericServlet,and HttpServlet classes for that methods..once refer J2EE API and find this classes and methods in them..
The JVM which runs the Servlet, looks for those methods only in classes, which extend Servlet or HttpServlet.
Servlets are managed objects. This means that they are executed inside a container that manages their lifecycles (instantiates the servlets, call their relevant methods when it is appropiate, and releases them). The container (Tomcat, Glassfish, ...) knows when to call these methods at the right time because it is implemented that way, there is nothing special about that.
If the container had a bug, it could even call, say, destroy() at init time and init() at destroy time. That bug would be fixed quickly, though.

Do I have any method to override System Properties in Java?

I am getting a practical issue and the issue can be dascribed as follows.
We are developing a component (Say a plugin) to do some task when an event is triggered within an external CMS using the API provided by them. They have provided some jar libraries, So what we are doing is implementing an Interface provided by them. Then an internal method is called when an event is triggered. (The CMS is creating only one instance of class when the first event triggers, then it just executes the method with each event trigger)
The function can be summarized as follows,
import com.external.ProvidedInterface;
public class MonitorProgram implements ProvidedInterface{
public void process(){
//This method is called when an event is triggered in CMS
}
}
Within our class we are using "javax.net.ssl.HttpsURLConnection" (JAVA 1.5). But HttpsURLConnection migrated to javax.net.ssl from com.sun.net.ssl for 1.4. But it seems the CMS I am referring to (We dont know their implementation actually) uses something like this
System.setProperty("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");
leading to a ClassCastException in our code.
I think my question is clear. In our case we cant set VM parameters,
-Djava.protocol.handler.pkgs=
Also we cant set it back using,
System.setProperty("")
because the VM instance is same for CMS and our program.
What can I do for get this problem resolved? And idea or experiences?
This is not clear for me.
Do you want to overwrite a system property?
You can do this.
Overwrite the System.property before calling the external library method and when the method returns you can set the old System.property back
final String propertyName = "Property";
String oldProperty = System.getProperty(propertyName);
System.setProperty(propertyName,"NEW_VALUE");
monitorProgram.process();
System.setProperty(propertyName,oldProperty);
Or do you want to prevent, that the called process overwrites the system.property?
And why you can not set the system property by hand?
I don't think you are going to have much success getting two pieces of code to use different properties.
In your own code however, you can define your own URLStreamHandlerFactory. Doing this will allow you to create a javax.net.ssl.HttpsURLConnection from a URL. While protocol handlers aren't the easiest thing to figure out, I think you can get them to do the job.
See http://java.sun.com/developer/onlineTraining/protocolhandlers/
Find the offending class in the stack trace
Use jad or a similar tool to decompile it.
Fix the name of the property
Compile the resulting file and either replace the .class file in the CMS's jar or put it into a place which is earlier in the classpath.
Use ant to automate this process (well, the compile and build of the JAR; not the decompiling)
When it works, make sure you save everything (original file, changed file, build file) somewhere so you can easily do it again.
While this may sound like a ridiculous or dangerous way to fix the issue, it will work. Especially since your CMS provider doesn't seem to develop his product actively.

Categories

Resources