Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 7 of 7
  1. #1
    Regular Coder Apothem's Avatar
    Join Date
    Mar 2008
    Posts
    380
    Thanks
    36
    Thanked 25 Times in 25 Posts

    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.

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    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.

  • #3
    Regular Coder Apothem's Avatar
    Join Date
    Mar 2008
    Posts
    380
    Thanks
    36
    Thanked 25 Times in 25 Posts
    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.

  • #4
    Regular Coder
    Join Date
    Feb 2008
    Location
    Edinburgh - Scotland
    Posts
    107
    Thanks
    0
    Thanked 12 Times in 12 Posts
    I am interested in why you want to do this at all?

  • #5
    Regular Coder Apothem's Avatar
    Join Date
    Mar 2008
    Posts
    380
    Thanks
    36
    Thanked 25 Times in 25 Posts
    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.

  • #6
    Regular Coder
    Join Date
    Feb 2008
    Location
    Edinburgh - Scotland
    Posts
    107
    Thanks
    0
    Thanked 12 Times in 12 Posts
    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!

  • #7
    New to the CF scene
    Join Date
    Dec 2011
    Posts
    4
    Thanks
    1
    Thanked 0 Times in 0 Posts
    You can use spring framework to do this.


  •  

    Posting Permissions

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