Results 1 to 7 of 7
  1. #1
    zibilico is offline Member
    Join Date
    Mar 2010
    Posts
    4
    Rep Power
    0

    Default How can I share a static field between 2 class loaders?

    Hi,

    I've been googling for 2 days and it now seems I'm not understanding something because nobody seems to have my problem. Please, somebody tell me if I'm crazy.

    The system's architecture:

    I've got a web application running in a SunOne server. The app uses Struts for the MVC part and Spring to deal with business services and DAOs.

    Beside the web app, beyond the application context, but in the same physical server, there are some processes, kind of batch processes that update tables and that kind of stuff, that run once a day. Theese processes are plain Java classes, with a main method, that are executed from ".sh" scripts with the "java" command.

    What do I need to do?

    "Simple". I need one of those Java processes to use one of the web app's service. This service has some DAOs injected by Spring. And the service itself is a bean defined in the Spring configuration file.

    The solution is made-up of 2 parts:

    1. I created a class, in the web app, with a static method that returns any bean defined in the Spring configuration file, or in other words, any bean in the application context. In my case, this method returns the service I need.

    Java Code:
    public class SpringApplicationContext implements ApplicationContextAware {
    	
    	private static ApplicationContext appContext;
    	
    	public void setApplicationContext(ApplicationContext context) throws BeansException {
    		appContext = context;
    	}
    	
    	public static Object getBean(String nombreBean) {
    		return appContext.getBean(nombreBean);
    	}
    }

    The ApplicationContext is injected to the class by Spring through the setApplicationContext method. This is set in the Spring configuration file.

    Well, this works fine if I call the getBean method from any class in the web app. But that's not what I need. I need to get a bean from outside the web app. From the "Java batch process".

    2. Why doesn't it work from outside the web app? Because when I call getBean from the process outside the web app, a different class loader is executed to load the SpringApplicationContext class. Thus, the static field appContext is null. Am I right?

    So, the question I need you to please answer me, the question I didn't find in Google:

    How can I share the static field between the 2 class loaders?

    If I can't, how can I load the SpringApplicationContext class, from the "Java batch process", with the same class loader my web app was started?

    Or, do I need to load the SpringApplicationContext class again? Can't I use, from the process, the class already loaded by my web app?

    I' sorry about my so extensive post...

    Thank you very much!

  2. #2
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    The purpose of using multiple class loaders is create "boundaries" around class definitions, so a group of classes can be "flushed" and reloaded without stopping the JVM. This also allows the same class to be loaded multiple times but treated as separate classes. Each version of the class has its own set of static fields, which is what is causing your problem.

    First, I would suggest that you avoid attempting to hack around this problem, except as a short term fix if this is a production system and the problem has to be corrected immediately.

    I have a couple of thoughts. A Spring container is made to hold everything that is going on. Trying to reach into it, especially when it is running in a Web application context, is not a good approach.

    One fix would be to bring these once-a-day processes into the Web application context. You can either run them off a trivial job scheduler thread (basically, just a wait), or you can set up a Web service front-end and invoke them externally. This approach makes sense if your overall application is relatively small.

    If you application is larger, so that you might have several Web applications accessing the same back-end, then separating the view logic from the model logic makes sense. That would involve setting up a separate Spring container for the model and providing a front-end for it, perhaps through Web services that are accessed only by the view applications. You gain flexibility at the cost of complexity.

  3. #3
    zibilico is offline Member
    Join Date
    Mar 2010
    Posts
    4
    Rep Power
    0

    Default

    A Spring container is made to hold everything that is going on. Trying to reach into it, especially when it is running in a Web application context, is not a good approach.
    I agree with you, but I don't have any choice. The application server and these once-a-day processes are already in production. Moreover, I can't run these processes from the web app nor add them to the application context because of some functional matters.

    you can set up a Web service front-end and invoke them externally
    I don't understand this. Could you explain further?

    Maybe, I'll finally set up a separate Spring context, that loads everytime I run the process. It'll have it's own Spring configuration files (these will be a fragment of the web app's config files), where I'll define only the beans I need to use, say the service and the 2 DAOs, and also the DB connection. Additionally, I'll set the classpath to use the beans classes of the web app. Thus, if the service and DAOs were modified in the app server, the process would load the modified classes in the following execution.

    Anyway, thank you very much for your time. It helped me to clarify that Spring is not intended nor prepeared to do what I need.

  4. #4
    PhHein's Avatar
    PhHein is offline Senior Member
    Join Date
    Apr 2009
    Location
    Germany
    Posts
    1,430
    Rep Power
    7

    Default

    Math problems? Call 1-800-[(10x)(13i)^2]-[sin(xy)/2.362x]
    The Ubiquitous Newbie Tips

  5. #5
    zibilico is offline Member
    Join Date
    Mar 2010
    Posts
    4
    Rep Power
    0

    Default

    Yes, I posted in that forum too. I needed answers! Is that wrong?

  6. #6
    PhHein's Avatar
    PhHein is offline Senior Member
    Join Date
    Apr 2009
    Location
    Germany
    Posts
    1,430
    Rep Power
    7

    Default

    What do you think will happen if someone posts a long reply here just to find out that you already got the same answer somewhere else? - He'll be pissed and most likely won't help you again. If you have to multipost, announce it and link to the other threads, so people can check whether you got replies already, before wasting their time.
    Math problems? Call 1-800-[(10x)(13i)^2]-[sin(xy)/2.362x]
    The Ubiquitous Newbie Tips

  7. #7
    zibilico is offline Member
    Join Date
    Mar 2010
    Posts
    4
    Rep Power
    0

    Default

    You are right PhHein. I'm sorry, I didn't realized.

    Anyway, I shouldn't delete these 2 threads now because they have already been answered. I will add a link to this thread in the other thread as you did here.
    Last edited by zibilico; 03-09-2010 at 01:38 PM.

Similar Threads

  1. Replies: 3
    Last Post: 02-09-2010, 05:22 AM
  2. can I use scanner as class field?
    By gcampton in forum New To Java
    Replies: 13
    Last Post: 11-10-2009, 02:07 PM
  3. static final field
    By techie.it19 in forum New To Java
    Replies: 3
    Last Post: 10-16-2008, 04:12 AM
  4. Class Reflection: Finding field infomation
    By Java Tip in forum java.lang
    Replies: 0
    Last Post: 04-23-2008, 08:09 PM
  5. Getting class field information using Reflection
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 01-24-2008, 03:20 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •