Global Variables in Java EE

Home

News: Global Variables in Java EE

  1. Global Variables in Java EE (34 messages)

    One of the TSS discussion forums asks about how to create safe global variables in EJB3: "Our server has to cache various kinds of data with quite complex structure. We can't simply read the data from database for each request because performance would be unacceptable. We need to store the data somewhere in memory to have fast access to it."
    For now we just [ignore] this restriction and our server code running in JBoss successfully uses static class fields to store global data. We never had problems during development but we never run the code in serious production environment. Can static class fields really cause trouble and why? Is there any other *portable* means to keep global variables ? We could use JBoss Cache but we don't want to bind ourselves to JBoss.
    It's an interesting problem. If you need to store reference data in a JavaEE application, what's the best way to portably do it? Would you load it into JNDI on application startup, refreshing occasionally as data is updated? Would you use a JCA component to retain the information? What suggestions would you have?

    Threaded Messages (34)

  2. Re: Global Variables in Java EE[ Go to top ]

    Can static class fields really cause trouble and why? /blockquote> Static fields is valid within one JVM. If you have more than one application server, each application server has its own JVM. The static fields are not synchronized among different JVMs. If you change any of them, you need to change all of them at the same time. JNDI is not a good solution. It is heavy: the admin servers has to send the JNDI data to all servers periodically. If you put many variables on JNDI, you need watch the performance price. By the way, there is an open source GlobalProperties at http://www.acelet.com/opensource/. It provide a convenient way to manage your global environment. Wei Jiang J2EE tools
  3. Re: Global Variables in Java EE[ Go to top ]

    Static fields is valid within one JVM. If you have more than one application server, each application server has its own JVM. The static fields are not synchronized among different JVMs. If you change any of them, you need to change all of them at the same time.
    Not necessarily. If the idea is just to cache data from the database, you can have one cache per VM. If the data must always be synced-up, well that's a more difficult problem. There's really no good way to do that with out some tolerance (be it a millisecond or a minute) for inconsistent data. Even complex distributed caching systems like Coherence have this caveat. I'm not sure, though, whether using static is really 'allowed'. I know creating your own threads is not because it screws up the app server's ability to manage it's own memory. Static can have the same effect. Having said, that I have created a cache in a J2EE server (long ago) that used it's own threads. The biggest problem we saw was that hot deployments would result in orphaned caches. The old class was not unloaded. But that was a dev only issue.
  4. Re: Global Variables in Java EE[ Go to top ]

    Having said, that I have created a cache in a J2EE server (long ago) that used it's own threads. The biggest problem we saw was that hot deployments would result in orphaned caches. The old class was not unloaded. But that was a dev only issue.
    There is much fun to be had with threads and statics in J2EE. If you think about how an app server manages transactions for an EJB, it must be that the transaction is committed/rolled back when the managed thread returns control to the container. DB operations on other threads must fall outside of the management of the container (because they never return). I know that marking your own threads as Daemons in a servlet container can cause Weblogic to fail to shut them down when you redeploy (which is the opposite to what I expected). Perhaps starting your own threads in a servlet container is banned too, but in the old days using the init() method on a servlet to start threads was the only way to get background tasks done. I have used statics to cache data many times. It can be dangerous in the wrong hands (that's me folks!). Remember that pass-by-reference can cause a reference to your object (and thus the class and all objects statically referenced) to be held within a different application, so redeployment does not clear them down. Weblogic 9.1 passes by reference when it finds anything unserialisable defined as a parameter in an EJB remote interface, say java.util.List.
  5. Re: Global Variables in Java EE[ Go to top ]

    Can static class fields really cause trouble and why? /blockquote>
    Static fields is valid within one JVM. If you have more than one application server, each application server has its own JVM. The static fields are not synchronized among different JVMs. http://www.acelet.com/opensource/. It provide a convenient way to manage your global environment.

    Wei Jiang
    J2EE tools
    Also to be statics is not on a "per-VM" basis, it's per type, not per-class as is the normal misconception. If the class is loaded in multiple classloaders they will have their own statics. Cheers,
  6. Using JavaSpace[ Go to top ]

    I would store reference data in JavaSpace. I would also write a proxy which will be registered in Lookup Service with JoinManager. The proxy will be a smart proxy and will have methods to retrieve data from space.
  7. Re: Global Variables in Java EE[ Go to top ]

    Before anyone proposes the use of a data grid solution ;-) I suggest looking at how this has been achieved since day one of the EJB 1.x specification - stateless session beans!! The obvious benefit being that one can at least reload it within a transactional context provided by the standard infrastructure. It is also possible to have a timed refresh of the reference data within the service method. Depending on the peak request concurrency on the actual bean reference this approach might create multiple instances of the bean (containers are allowed to create multiple instances) and cached data in memory with possible discrepancies due to time of load but I assume this last issue is not such a problem because of nature of the data (reference like). The loaded data can be stored in a normal instance field (yes stateless beans can have state, just not conversational) or if you really want to limit possibility of multiple copies you can have the bean store it in JNDI service. Please note that the java:comp/env is read-only though some containers have not always adhered to this. Regards, William Louth JXInsight Product Architect CTO, JInspired "Java EE tuning, testing, tracing, and monitoring with JXInsight" http://www.jinspired.com
  8. Re: Global Variables in Java EE[ Go to top ]

    Before anyone proposes the use of a data grid solution ;-) ..
    I would only suggest it if you had more than one server .. ;-) Peace, Cameron Purdy Tangosol Coherence: The Java Data Grid
  9. Session Beans[ Go to top ]

    Stateless session beans have a few disadvantages. The server can create multiple instances. Since the container assumes that session beans are not thread-safe, it will create at least as many instances as there are concurrent requests. (I don't remember any flag in the deployment descriptor that would allow bean instances to be shared.) Each instance will contain its own cache. This can use up quite a bit of memory. In the past, I have successfully used a singleton class to manage a cache inside an EJB container (Websphere). As long as you're not caching bean instances, you should be OK.
  10. Re: Session Beans[ Go to top ]

    (I don't remember any flag in the deployment descriptor that would allow bean instances to be shared.)
    Just to be clear instances are pooled and restricted to servicing only one request at a time. Excluding the actual initial loading of the cache the likelihood of having a very large number of instances in memory is pretty small unless the bean is doing more than simply returning the cached data in a method. You would really need an impressive hardware setup to get the instances high or a extremely slow component-to-component request dispatching system. Look I am sure that one can create a singleton class that appears to work fine in any container but it is not compliant with the specification because the authors tried to simplify the programming model for bean component developments to ensure a higher probability of scalability and reliability for deployed systems. If you look at the latest release notes for JBoss messaging you can see that even the system experts have troubling ensuring the liveliness of sub systems. http://jira.jboss.com/jira/browse/JBMESSAGING-660 By the way the interface to the cache data structure should be immutable otherwise you will have even more issues pushed outside the request processing of the cache facade session bean. Regards, William
  11. Re: Session Beans[ Go to top ]

    I agree with your solution. However, if you really want to code to the specs, you can't ignore that a container might very well choose not to pool session bean instances at all. Creating a new instance for every method call is perfectly valid for a container. In which case, this solution wouldn't work. Moreover, if you want to cache reference data taking 2 megs of memory, duplicating these 2 megs in 80 pooled session beans is not really a good option IMHO. It seems to me that the "no static variable" rule in the spec is there to prevent developers shooting themselves in the foot: they should realize that static variables are only accessible from other components in the same VM, and that they don't work anymore in a cluster. Having realized that, and knowing that each JVM may have a different read-only cache, I don't see why using a static variable or a singleton would cause any problem. BTW, how can you be sure that no class in the myriad of classes from J2SE and all the libraries your application uses (utilities, logging, etc.) doesn't use static variables and synchronized blocks? They use them, and it isn't a problem. If they use them without problem, your code can use them as well. JB.
  12. Re: Session Beans[ Go to top ]

    ...how can you be sure that no class in the myriad of classes from J2SE and all the libraries your application uses (utilities, logging, etc.)
    Hi Jean, The view is that such libraries would have been created by an experienced system developer who would had much more time and focus to concentrate on additional concerns (performance, concurrency,...). Of course this is not always the case in the real-world but solving the software engineering quality problem is outside the scope of the specification. Yes there are popular libraries today that internally use statics. We all know this because we have seen various thread safety issues (bugs) being reported on library forums for production systems. A scan of the such forums or product release notes will validate the usage of such shared access constructs (static and non-static) that have caused problem in production systems. Regards, William
  13. Re: Session Beans[ Go to top ]

    Though the Thread(I mean discussion thread not Java thread..) is very old..but still I cannot stop appreciating various views expressed..
  14. Re: Global Variables in Java EE[ Go to top ]

    I just couldn't help myself ;) Use a "Data Grid Bean" in Spring. http://www.tangosol.com/coherence-spring.jsp Permits both heavy read and heavy thread-safe update characteristics across a Data Grid without locking (or a container!) -- Brian ------------------------------------------------- Brian Oliver Data Grid Solutions Architect Tangosol Inc.
  15. Resource Adapter[ Go to top ]

    Simple... Write a JCA adapter/component that handles the caching. Been there, done that.
  16. Re: Global Variables in Java EE[ Go to top ]

    There is nothing wrong with using a static class for holding data as long as you provide a reload method for refreshing data while running. As pointed out already, this will not work if you need to access data accross JVM's. Also, this does not have to be EE, J2SE etc will work great too. Where is this pattern useful? If you have standard data that you consistently access but rarely changes, or, read and near-read only data. I use this to information about locations, product types, customer types, etc. This can actually provide 3x or more improvement in speed for things like the retrieval and display of large reports while decreasing memory usage. Sample: private static boolean isCacheLoaded = false; public static boolean isCacheLoaded() { return isCacheLoaded; } public static void reload() { // Reload work here isCacheLoaded = true; } private MyProduct[] product = null; public static String getProductName(int id) { // You could use a hash also if (!isCacheLoaded) reload(); for (int i=0; i < product.length; i++) if (product[i].ID == id) return product[i].name; return ""; }
  17. Re: Global Variables in Java EE[ Go to top ]

    Programming Restrictions:
    An enterprise bean must not use read/write static fields. Using read-only static fields is allowed. Therefore, it is recommended that all static fields in the enterprise bean class be declared as final.
    This should have been extended to the fields of the reference object and its direct/indirect references if of a non-primitive type.
    An enterprise bean must not use thread synchronization primitives to synchronize execution of multiple instances.
    Clearly these two issues should rule out the use of static immutable fields for caching data unless someone can explain to me how one goes about accessing a managed resource from within a static block of a class (bean or helper) in a standard and secure way. Regards, William Louth JXInsight Product Architect CTO, JInspired "Java EE tuning, testing, tracing, and monitoring with JXInsight" http://www.jinspired.com
  18. Re: Global Variables in Java EE[ Go to top ]

    Right, So you should use a singleton class. This will solve your issues...I should have posted that in my example. We are using this in multiple J2EE/J2SE JVM environments on very large high traffic ecommerce sites with no issues whatsoever.
  19. Re: Global Variables in Java EE[ Go to top ]

    Will, Easy, use async beans in WebSphere. I don't think the commonj spec includes the EventProxy capability in the async beans APIs. This lets you snapshot the context on a container thread and then call code later with the same context potentially on a different thread. All contexts except tx are preserved. As far as what the spec says, fine, don't have statics in an Enterprise bean, have it in a POJO instead...
  20. Re: Global Variables in Java EE[ Go to top ]

    Hi Billy, Is this similar to the CORBA Activity Service? Regards, William
  21. Re: Global Variables in Java EE[ Go to top ]

    Sorry but the above disqualifies the usage of a singleton class for the purpose of a data cache (at least by a business component developer). In general most of the restrictions within the specification extend to deployed classes that a component calls unless the class was implemented by a system developer and deployed a JCA resource adaptor. But using JCA seems overkill for such a problem with a rather simple solution (stateless session bean). Once one takes off the blinkers and sees pass the singleton class option it really is not worthy of a posting on the front page of TSS. Regards, William
  22. Re: Global Variables in Java EE[ Go to top ]

    Well, If you are looking at business components as seperate entities not designed specifically for a particular deployment, then yes, its inappropriate...but that was not stated as a requirement. But, a POJO singleton will work very well for the initial situation described. Sometimes the simplest answer is the right one and you don't need to get complex or start a p'ing contest because you don't like another view. This pattern is a GREAT way to replace read-only entity beans too. I can tell you that this pattern has been implemented with great success on what was the largest installation of BEA/Windows at the time, and on ATG/Solaris, JBoss/Windows, and Resin/Windows in large ecommerce and b2b sites.
  23. Re: Global Variables in Java EE[ Go to top ]

    Sometimes the simplest answer is the right one and you don't need to get complex or start a p'ing contest because you don't like another view.
    Nobody is starting a pissing contest. I know the Singleton solution works here because I have used it. But that doesn't change that it's disallowed by the spec. I don't know the specific reason why it's disallowed off-hand or whether it's really a good reason but it's definitely outside of the spec to do this. If you want to follow the spec, you can't do this. I remember reading an article years ago explaining why each J2EE restriction existed. I'm sure if someone hunted around a bit they could find an explanation. My guess/memory is that could keep the app-server from managing it's resources effectively. Whether is actually does in any common implementation would take a bit more work to determine.
  24. Re: Global Variables in Java EE[ Go to top ]

    I know why it is forbidden, there is no such thing like a singleton in an application server except you use external objects like a JCA adaptor or an object accessed via JNDI. All the solutions mentioned here fail with the first redeployment. You can create singletons with static objects only on a per classloader base. It is common for application servers to create a new classloader for each deployment. Sessions connected with the old classloader use the old singleton and new sessions get the new singleton. And ups your singleton is a doubleton. If you can undeploy/deploy for each update you can use a singleton using static variables. If you require 24x7 availability you can not use it. A JCA adaptor works because its classloader is the application servers classloader, same is true for JNDI objects.
  25. Re: Global Variables in Java EE[ Go to top ]

    All the solutions mentioned here fail with the first redeployment. You can create singletons with static objects only on a per classloader base. It is common for application servers to create a new classloader for each deployment. Sessions connected with the old classloader use the old singleton and new sessions get the new singleton.
    FWIW - Coherence is classloader aware, and supports hot redeployment on app servers and sharing objects across different apps running on the same app server (with different class loaders). Peace, Cameron Purdy Tangosol Coherence: Clustered Caching for Java
  26. Re: Global Variables in Java EE[ Go to top ]

    And how many times does one actually hot-redeploy an application into a production environment. I am assuming you are not try to save precious cpu cycles on a developer workstation so your hot deploys are faster. Most of the companies I have visited have one application per server process and every time there is a change to a software artifact a complete change management process is initiated which involves the (staggered) restart of every instance of the application. Even if one did consider hot-deployment suitable in a production environment, which by the way is extremely unlikely with current levels of quality in both containers and application implementations, the cost of the deployment of the application would be relatively high compared to any reloading costs of cached referenced data. If we are talking about a monstrous amount of data then it would be much more appropriate to consider using a data grid solution, did I say that, to offset the costs across all those planned and unplanned server restarts (why stop at the classloader?). A stateless session bean is a relatively straight forward solution to most reference data caching requirements. If you need to get anymore sophisticated than this then it would probably be best just using an off the shelf caching solution than developing a JCA adaptor. By the way I think you will find that it is possible to bind objects into a naming service without the class of the bound objects being on the applications server class loader. Whether this is allowed by the specification and supported on all platforms is a different matter. Regards, William
  27. I typically write web apps with little or no other J2EE features, but am deploying to a cluster (BEA WebLogic). I typically only cache objects in the ServletContext, but usually just items that don't change very often, and if they do, worst case is redeploy to refresh the cache. Crude but it works. I'm starting to think about performance and caching now (would like to cache items that change more frequently), so my question is whether ServletContext is typically replicated in a cluster, and if so, what is the trigger to synch it up (time event? changed object? new entry?)?
  28. Use JMS[ Go to top ]

    Hello, I suppose a good trade-off between performance and coding complexity is to use JMS to synchronize each distributed cache instance. By letting a resource on the same application server as the clustered application do the work, you also avoid creating a single point of failure. There is an interesting article here: http://www.oracle.com/technology/pub/articles/masterj2ee/j2ee_wk6.html Yann
  29. Re: Global Variables in Java EE[ Go to top ]

    We could use JBoss Cache but we don't want to bind ourselves to JBoss.
    If you need multi-JVM caching, JBoss Groups could be used too. JBoss Groups is not tied to any application server.
  30. Re: Global Variables in Java EE[ Go to top ]

    There are some good cache technologies out there: ehcache and OSCache (not proprietary solutions, open source). Not particularly difficult to use. It is the good solution if you have multiple app servers. For only one serveur, I use static fields successfully (same JVM and Classloader). Even if it may be forbidden by the specs ;) ). It is the easiest solution. Jboss cache may also be a good solution (it is not proprietary, I don't know if it is distributed). Tangosol Coherence and Gigaspaces are (good) solutions for very distributed environment; as I understand, it seems it's not your situation. Cyril
  31. Re: Global Variables in Java EE[ Go to top ]

    No one has mentioned putting your global data in an MBean. I have an MBean that caches some database stuff currently deployed in production. I *do* like the idea of putting it in a stateless session bean, though. Hadn't thought of that! Steve
  32. Re: Global Variables in Java EE[ Go to top ]

    And noone mentioned entity beans... I've used them successfully in several projects ;) You can tune the app server pool for the beans, have TXs and readonly entity beans. Cluster replication can be automatic... Yes, you need to know all the many configuration options and caveats, but after all I think they are close to perfect for storing ref. data in memory (in the container managed pool). But of course that is just for those pressed by management not to use jboss cache or some other suitable caching solution :) peace
  33. Re: Global Variables in Java EE[ Go to top ]

    I use Singleton Class + JMS (MDB inside the container, regular listener outside)
  34. Not cool[ Go to top ]

    I'm using ThreadLocal but it is not a cool API. Are there any problems for using that?
  35. I put my constants in the application context.