• 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

Accessing a Class in the ServerContext

 
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
In my web app I have several objects I am creating at the application server level.
In my servlets I access them using request.servletContext then I pass this reference into my java class methods.

I there a way for the java class methods to access these objects directly from the servletContext?

Say my java class has three methods, currently I pass the object to all three when I would like to have it static in the class so it would be accessible to all three methods.
 
Saloon Keeper
Posts: 15484
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why? Because it's more convenient? Bad idea. In fact, I find it very suspicious that you have extra data in your servlet context in the first place.

What kind of objects are these, and why don't you retrieve them from a repository rather than the servlet context?

If these really are objects that must remain in memory and be globally accessible (they MUST be immutable), register them with your IoC container as singletons. In Spring, you can do that with the @Component (on a class) or @Bean (on a method) annotations.
 
Saloon Keeper
Posts: 27752
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I cannot make any sense of this. For one thing, a ServletContext is a data structure, not code, so it's not going to be accessing anything in its own right.. And it is, in fact, an interface, so the webapp server's implementation class is likely to contain all sorts of unexpected (and private!) things. You don't want to get creative with this thing, or a future change in the appserver can cause your app to crash in unpredictable ways

Finally, the way to share objects within a web application is simply to store them in application scope. That's what it's for. They don't have to be immutable, although if they are not, they should usually be synchronized.


Now if you really do expect to share objects in memory between multiple applications in an appserver, that is very much discouraged. Each webapp should be completely independent of every other webapp. They each have their own unique classpaths. Any communications or sharing between them should preferably be done via a (loopback) network connection or similar interface. For one thing, if you ever intend to scale up and run a cluster, direct RAM sharing only works within a single VM (server instance). In general, any expected efficiencies that you'd get from brute-force object sharing are not going to be worth the price.

What you probably need isn't so much a shareable class as a shareable service. That is, something that each app can serve as a client for.
 
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

Tim Holloway wrote:I cannot make any sense of this. For one thing, a ServletContext is a data structure, not code.



I am not intending to share objects across my applications.
My situation was for example: I have a dropdown list where the user selects an option.
The content for this dropdown comes from a remote data source.
The content was retrieved when a session of the application was loaded. So 100's of users were adding the same object in memory for each session instance.
So I found an article where I could use contextInitialized(ServletContextEvent servletContextEvent) to do this work(add the list content at the application scope) and
use request.getServletContext().getAttribute() to get the dropdown content. Then I pass this to the necessary classes that use this dropdown context. This seems to work okay.

I was just asking if there is a way for a java class to access this server level object without have to use the servlet to pass a reference to the java class.
 
Stephan van Hulst
Saloon Keeper
Posts: 15484
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It sounds like you just want to cache information retrieved from the external source. Again, I don't know whether you're using a web application framework (I really recommend it), but as an example, if you're using Spring you would make the component method that retrieves the values from the external service @Cacheable. They will then automatically be cached somewhere appropriate in the application scope, and you don't have to hack around with the servlet context or global variables.
 
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To answer the question, no, there is no way for non-servlet classes to access the application content (aka servletContent). You might be tempted to pass the servletContent around -- DON'T DO IT. Just pass the data as necessary.

Most of the time such information (dropdown lists) are going to be used in a JSP, so no passing is necessary; JSPs have direct access to the application content. What is the use case where you need to pass this sort of information deeply within a call tree?
 
Tim Holloway
Saloon Keeper
Posts: 27752
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
I've had apps like that. What I did was create the menu collections as Application Scope objects and have the various Views that use the menu simply reference those objects by name. It's a natural fit, not only for JSP/JSTL but for many other frameworks like JSF and Struts.

There are at least 2 ways to do this. One is via the contextInitialized hook in ServletContext, another is to built on-demand and cache.

The downside of using contextInitialized is that you don't want to do too much heavy lifting at application startup if you can avoid it. I once inherited an app that loaded half the database in RAM at startup, so the app didn't actually become usable for 20 minutes. And that's bad enough in production, but it's a major pain when testing.

The downside of on-demand building is that the first user to invoke it has to pay the penalty of waiting while the menu data is collected and cached. This speeds up startup, and usually the extra delay for the first user isn't too objectionable, although that can vary depending on how complex your menus are and how large they are.
 
reply
    Bookmark Topic Watch Topic
  • New Topic