• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

programmably reload servlet context data

 
Ranch Hand
Posts: 188
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I set certain variable into the servlet context. If i change them the context need to be reloaded for them to take effect. Is there a way to reload the context after i make a change without restarting tomcat?

TIA
John
 
Ranch Hand
Posts: 261
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't think you need to restart Tomcat to reload the context. Undeploying and re-deploying the web application will work just as well. However, you can't do so programmatically from within your web application.
And if I'm not wrong, Tomcat has the ability to detect a change in the web descriptor [web.xml] of any deployed application and automatically re-deploys it.

I am assuming by changing the value of context variables you mean changing them in the web.xml.

Otherwise, if you're changing attribute values using the ServletContext interface, then I think the change is visible to all servlets instantaneously. Though you need to have the mechanism present in your servlets to keep a check on any changes. Alternatively, you can put to use the ServletContextAttributeListener to update the value of attributes in a common lookup data-structure, which all servlets use to retrieve attribute values.
 
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just to add to Arindam's comments:

You can just do "touch" to web.xml and it will reload the application. You can find alternative command to touch on windows over the net.

Please note that you will lose all the current sessions during this process so this is preferred only in dev environment.
 
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I set certain variable into the servlet context. If i change them the context need to be reloaded for them to take effect.


This makes no sense to me. Can you explain what you mean by "set certain variable into the servlet context", because what this means to me makes no sense with the rest of the statement.
 
John Schretz
Ranch Hand
Posts: 188
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry let me explain it better. Below is the context listener i use to load an array list to be used in multiple places on the site. However if i make a change in the database i have to reload tomcat so the arrayList will update with the new change. I want to be able to do this without restarting tomcat.

 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Of course you don't have to restart Tomcat. Just replace the scoped variable in the servlet context. What's with the idea that things need to be restarted?

Of course, your code has no way of automatically knowing that the DB has changed. How do you want to notify the application that it's time to reload the variables?
 
John Schretz
Ranch Hand
Posts: 188
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a screen that has a bunch of options for the vendors. So when i hit save on that screen and update the DB, I would like to reload the context.
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Is this from within the same application? If so, this is easy.

What I would do is to create a factory class who's job it is to supply the information rather than storing the info in servlet context. All parts of the application obtain the info from this class (which itself can live in servlet context) rather than directly.

With this abstraction in place, how the data is actually handled is moot as far as the rest of the app is concerned. Abstraction is our friend!

When someone asks for the data, this factory is smart enough to go fetch the data if it doesn't already have it cached internally. Once fetched, subsequent requests for the data simply return the cached data.

When an operation that invalidates the data is executed, it can tell the factory to dump the cache. That way, the next time that the data is asked for, the factory will know to go and reload it from the DB.
 
John Schretz
Ranch Hand
Posts: 188
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes its in the same application. If I use Factory, would i discontinue the use of the context listener? Do you have a link for a factory tutorial? I know a little bit about them but never really coded using factory. THis sounds like something i would like to try.
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The listener would be used to instantiate the data factory and place it in servlet context for all to use, perhaps better called a "data cache".

There's nothing special about coding it up. Just create a class with the methods that you need.
 
John Schretz
Ranch Hand
Posts: 188
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ok so i can do something like


in my jsp i can have:

${factory.getVendors}

which will return my vendor list

Im just not sure on how to tell what is cached or not.
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

John Schretz wrote:ok so i can do something like


Yes, just name it something a little more descriptive than "Factory". Perhaps, VendorDataFactory, or (my choice) VendorDataCache.


in my jsp i can have:

${factory.getVendors}


No "get" in the EL, remember!

I'd make it so that the EL in the JSP would like something like:


Im just not sure on how to tell what is cached or not.



Within the VendorDataCache class you have an instance variable that stores the loaded data. If it's null when the data is asked for, you load it from the DB. Simple.

Then, there's a method, perhaps dumpCache(), that can be called to simply set the instance variable to null. The next time the data is asked for, the instance variable being null will trigger another database load.
 
John Schretz
Ranch Hand
Posts: 188
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ahhhhhhhhh that make perfect sense.
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is a very elegant way of dealing with the issue as the details of where the data is coming from is hidden from the application. All that the application parts need to do is to ask for the data, and it just gets it. Whether it has to be loaded from the DB or not is completely hidden.
 
Ranch Hand
Posts: 2206
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:Is this from within the same application? If so, this is easy.

What I would do is to create a factory class who's job it is to supply the information rather than storing the info in servlet context. All parts of the application obtain the info from this class (which itself can live in servlet context) rather than directly.

With this abstraction in place, how the data is actually handled is moot as far as the rest of the app is concerned. Abstraction is our friend!

When someone asks for the data, this factory is smart enough to go fetch the data if it doesn't already have it cached internally. Once fetched, subsequent requests for the data simply return the cached data.

When an operation that invalidates the data is executed, it can tell the factory to dump the cache. That way, the next time that the data is asked for, the factory will know to go and reload it from the DB.



I realize this is an old post but it is where I am at right now.

My data class:



My ServletContextListener code:



This works when application is initially started. However, I cannot understand how to do the refresh when the remote data changes.

Thanks for any help as always.
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Steve Dyke wrote:However, I cannot understand how to do the refresh when the remote data changes.



You cannot know when something external changes the data. You do know when your application takes an action that changes the data. If it is likely that the data changes externally, you should invalidate the cache at intervals that make sense with the frequency that the data changes and how important it is to your application that the data be up to date.
 
Steve Dyke
Ranch Hand
Posts: 2206
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:

You do know when your application takes an action that changes the data.



This what I have coded to check if cache is invalidated. Now will this set the cache back to the application level or only the session level?

 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Answer your own question: which line sets the data into a context? Is that context the session?
 
Steve Dyke
Ranch Hand
Posts: 2206
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:Answer your own question: which line sets the data into a context? Is that context the session?



Line#12 but just wandering about the scope of the request. I think I see the getServletContext() is application level while getSession() would be the session level.

Just wanted to make sure this code would affect any session of the application.
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Correct. Setting a value into the application context will not affect any session.
 
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:Correct. Setting a value into the application context will not affect any session.



Actually, I prefer saying "Application Scope Object."

While you do have to reference the servletContext to get application scope in some instances, in many cases, such as JSPs and injected objects such as JavaServer Faces ManagedBeans, it is sufficient to say "application scoped" via metadata or context and the JEE infrastructure will take care of the details. Using the term "application scope" is a good reminder of that.

Also, if you're using a framework such as Spring, you may also have another, unofficial global scope, which comes from the bean factory. I hesitate to call this "classpath scope", but it is a source of objects not stored within any of the JEE scope dictionaries but still local to that particular webapp instance. Since Spring is an Inversion of Control mechanism, such objects can then be injected directly where they are needed or obtained from the Spring bean factory. That's the case for things like JPA Persistence management (EntityManager) under partial-stack JEE servers such as Tomcat, as an example.

Speaking of JPA and persistence in general, I don't like the idea of using a constructor to get a database connection. It makes it appear as though you're not using connection pooling.
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:I don't like the idea of using a constructor to get a database connection. It makes it appear as though you're not using connection pooling.



Ding! Ding! Ding! Ding! Ding!
 
Steve Dyke
Ranch Hand
Posts: 2206
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:

Tim Holloway wrote:I don't like the idea of using a constructor to get a database connection. It makes it appear as though you're not using connection pooling.



Ding! Ding! Ding! Ding! Ding!



Not sure what I need to do different. I was under the impression that this code took advantage of Connection Pooling.
The new DataConnection constructor uses this code.

 
Tim Holloway
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are cleaner ways to do this. Why, in particular, define an entire class, construct it just to invoke one method and then discard the class object? You'd be better off using static methods, and we don't actually recommend static method ordinarily.

And as a general rule, you don't need a lot of IBM proprietary stuff just to get a JDBC Connection. I've never used any com.ibm stuff for iSeries JDBC, just vanilla Java JDBC stuff.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic