Go Back   CodingForums.com > :: Server side development > Java and JSP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 12-24-2011, 10:48 PM   PM User | #1
Apothem
Regular Coder

 
Apothem's Avatar
 
Join Date: Mar 2008
Posts: 380
Thanks: 36
Thanked 25 Times in 25 Posts
Apothem is an unknown quantity at this point
Class Loading: How to do it with Singletons?

Simply put, I want to dynamically load singletons.

i.e. Say I have:
Code:
public class Singleton {
  private static Singleton instance;
  private Singleton() {}
  public static Singleton getInstance() {
    if(instance == null) { instance = new Singleton(); }
    return instance;
  }
}
From what I have learned, you would do something like this if it wasn't a singleton:
Code:
MainClass.class.getClassLoader().loadClass("myClass").newInstance();
But I don't this will be allowed. Would I need another layer of indirection? For example, do I need to do:
Code:
public class SingletonLoader {
  public Singleton getInstance() { return Singleton.getInstance(); }
}
and from there invoke the getInstance method? Or is there a more direct solution?

Last edited by Apothem; 12-24-2011 at 10:52 PM..
Apothem is offline   Reply With Quote
Old 12-25-2011, 04:33 AM   PM User | #2
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
Singleton is designed for the instance of that class. I think that the call against a .newInstance off the class loader would chain to the constructor, so a private or protected constructor will throw an exception.
To load, its a simple call to Singleton.getInstance();. There is really no way to do this dynamically since you cannot stop an class with a public constructor from instantiating a new record. Any class to be a singleton has to be an instance of a Singleton first. You can call it against a dynamically loaded class though, that's just a simple try/catch and attempt to invoke the Method of getInstance on the class or cast to a Singleton type.

So if I got what you are looking for, your dynamically loaded classes implement singleton. You can load them as so:
PHP Code:
try
{
    
Method getInstance = class.getClassLoader().loadClass("MyClass").getMethod("getInstance");
    
Object instance getInstance.invoke();
}
catch (
Exception ex)
{
    
System.out.println(ex.getMessage());

Methinks that will work.
Fou-Lu is offline   Reply With Quote
Old 12-25-2011, 06:32 AM   PM User | #3
Apothem
Regular Coder

 
Apothem's Avatar
 
Join Date: Mar 2008
Posts: 380
Thanks: 36
Thanked 25 Times in 25 Posts
Apothem is an unknown quantity at this point
Well, after digging around I found out I was supposed to do something like:
Code:
          Class<?> c = Class.forName("MySingleton");
          Method m = c.getDeclaredMethod("getInstance", new Class[0]);
          Object obj = m.invoke(null, new Object[0]);
But I'm getting the following exception:
Code:
java.lang.NoSuchMethodException: MySingleton.getInstance()
        at java.lang.Class.getDeclaredMethod(Class.java:1954)
        at myProg.main(myProg.java:21)
Really strange because that class does in fact have a getInstance() method... as such:
Code:
  /**
   * Gets single instance of the site
   * @return the site
   */
  public static MySingleton getInstance() {
    if(instance == null) {
      instance = new MySingleton();
    }
    
    return instance;
  }
Note: I replaced the real singleton class name with "MySingleton".

Edit: Woops my bad, it seems that I was editing the wrong "MySingleton" file. It works. Thanks.

Last edited by Apothem; 12-25-2011 at 06:43 AM..
Apothem is offline   Reply With Quote
Old 12-25-2011, 04:12 PM   PM User | #4
renegadeandy
Regular Coder

 
Join Date: Feb 2008
Location: Edinburgh - Scotland
Posts: 107
Thanks: 0
Thanked 12 Times in 12 Posts
renegadeandy is an unknown quantity at this point
I am interested in why you want to do this at all?
renegadeandy is offline   Reply With Quote
Old 12-25-2011, 06:20 PM   PM User | #5
Apothem
Regular Coder

 
Apothem's Avatar
 
Join Date: Mar 2008
Posts: 380
Thanks: 36
Thanked 25 Times in 25 Posts
Apothem is an unknown quantity at this point
The project I am currently working on makes use of the ability to dynamically load classes. Why? I want to allow other developers to develop their own subsystem based on a set of interfaces I already have, and allow users to benefit from it.

I can technically make things very simple for myself and complicated for others, but I do not believe that is the way to go. And though it may sound hypocritical to say this, I would like to uphold certain invariant so that there is design. These invariant might cause the developer to do a LITTLE more work, but it is for the "greater good" so that recompiling the entire source is not required.
Apothem is offline   Reply With Quote
Old 12-25-2011, 06:29 PM   PM User | #6
renegadeandy
Regular Coder

 
Join Date: Feb 2008
Location: Edinburgh - Scotland
Posts: 107
Thanks: 0
Thanked 12 Times in 12 Posts
renegadeandy is an unknown quantity at this point
Ahhhh right I see - so the main goal is to make setting up easy so you dont need to recompile, hence why you need to deal with the classloader, gotcha, nice work!
renegadeandy is offline   Reply With Quote
Old 12-30-2011, 07:33 AM   PM User | #7
albert.chiu
New to the CF scene

 
Join Date: Dec 2011
Posts: 4
Thanks: 1
Thanked 0 Times in 0 Posts
albert.chiu is an unknown quantity at this point
You can use spring framework to do this.
albert.chiu is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 08:35 AM.


Advertisement
Log in to turn off these ads.