I was drawn inspiration from this stackoverflow question
How can one create a Java class instance that is guaranteed to be available only once for the entire JVM process? Every Application that runs on that JVM should then be able to use that singleton instance.
You can as a matter of fact implement such a singleton. The problem that was described to you in the comments is the possibility of a class being loaded by multiple ClassLoaders. Each of these ClassLoaders can then define a class of identical name which would erroneously assume to be unique.
You can however avoid this by implementing an accessor to your singleton which explicitly relies on checking a specific ClassLoader for a class of a given name which again contains your singleton. This way, you can avoid that a singleton instance is provided by two different ClassLoaders and such duplicating the instance you required to be unique throughout the JVM.
For reasons that are explained later, we will split up the Singleton and the SingletonAccessor into two different classes. For the following class, we need to later make sure that we always access it by using a specific ClassLoader:
package pkg;
class Singleton {
static volatile Singleton instance;
}
A convenient ClassLoader for this matter is the system class loader. The system class loader is aware of all classes on the JVM's class path and has per definition the extension and the bootstrap class loaders as its parents. Those two class loaders do not normally know about any classes that are domain-specific such as our Singleton class. This safes us from unwanted surprises. Furthermore, we know that it is accessible and known globally throughout a running instance of the JVM.
For now, let us assume that the Singleton class is on the class path. This way, we can receive the instance by this accessor using reflection:
class SingletonAccessor {
static Object get() {
Class<?> clazz = ClassLoader.getSystemClassLoader()
.findClass("pkg.Singleton");
Field field = clazz.getDeclaredField("instance");
synchronized (clazz) {
Object instance = field.get(null);
if(instance == null) {
instance = clazz.newInstance();
field.set(null, instance);
}
return instance;
}
}
}
By specifying that we explicitly want to load pkg.Singleton from the system class loader, we make sure that we always receive the same instance despite of which class loader loaded our SingletonAccessor. In the above example, we additionally make sure that Singleton is only instantiated once. Alternatively, you could put the instantiation logic into the Singleton class itself and make the unused instances rot in case other Singleton classes are ever loaded.
There is however a big drawback. You miss all means of type-safety as you cannot assume that your code is always run from a ClassLoader which delegates the class loading of Singleton to the system class loader. This is in particularly true for an application run on an application server which often implements child-first semantics for its class loaders and does not ask the system class loader for known types but first tries to load its own types. Note that a runtime type is characterized by two features:
Its fully-qualified name
Its ClassLoader
For this reason, the SingletonAccessor::get method needs to return Object instead of Singleton.
Another drawback is the fact that the Singleton type must be found on the class path for this to work. Otherwise, the system class loader does not know about this type. If you can put the Singleton type onto the class path, you are done here. No problems.
If you cannot make this happen, there is however another way by using for example my code generation library Byte Buddy. Using this library, we can simply define such a type at runtime and inject it into the system class loader:
new ByteBuddy()
.subclass(Object.class)
.name("pkg.Singleton")
.defineField("instance", Object.class, Ownership.STATIC)
.make()
.load(ClassLoader.getSytemClassLoader(),
ClassLoadingStrategy.Default.INJECTION)
You just defined a class pkg.Singleton for the system class loader and the above strategy is applicable again.
Also, you can avoid the type-safety issues by implementing a wrapper type. You can also automatize this with the help of Byte Buddy:
new ByteBuddy()
.subclass(Singleton.class)
.method(any())
.intercept(new Object() {
#RuntimeType
Object intercept(#Origin Method m,
#AllArguments Object[] args) throws Exception {
Object singleton = SingletonAccessor.get();
return singleton.getClass()
.getDeclaredMethod(m.getName(), m.getParameterTypes())
.invoke(singleton, args);
}
})
.make()
.load(Singleton.class.getClassLoader(),
ClassLoadingStrategy.Default.INJECTION)
.getLoaded()
.newInstance();
You just created a delegator which overrides all methods of the Singleton class and delegates their invocation to invocations of the JVM-global singleton instance. Note that we need to reload the reflective methods even though they are signature-identical because we cannot rely on the ClassLoaders of the delegate and the JVM-global classes to be the same.
In practice, you might want to cache the calls to SingletonAccessor.get() and maybe even the reflective method look-ups (which are rather expensive compared to the reflective method invocations). But this need depends highly on your application domain. If you have trouble with your constructor hierarchy, you could also factor out the method signatures into an interface and implement this interface for both the above accessor and your Singleton class.
Related
According to the Java 8 Language Spec §15.8.2 (quote):
[...]
A class literal evaluates to the Class object for the named type (or for void) as defined by the defining class loader (§12.2) of the class of the current instance.
[...]
Mainly, 'the Class object' insinuates that this is or should be a singleton. Also §12.2 says:
[...]
Well-behaved class loaders maintain these properties:
Given the same name, a good class loader should always return the same class object.
[...]
In fact, using Java 8*, the following** prints true and true:
class Main {
public static void main(String[] args) {
Main main1 = new Main();
Main main2 = new Main();
System.out.println(main1.getClass().equals(main2.getClass()));
System.out.println(main1.getClass() == main2.getClass());
}
}
Is the class loader always 'well-behaved' and why (not)? In other words: are Class instances singleton? The other way around: can a Class of the same type be a different instance?
Notes: I do not refer to the singleton pattern here. However, if the Class implementation follows that pattern, that would be interesting. As a side-step, but by no means the main question: because the singleton pattern's legitimate uses are point of debate, would Java's Class be a good candidate to apply the singleton pattern to?
*:
$ java -version
openjdk version "1.8.0_262"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_262-b10)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.262-b10, mixed mode)
**: my IDE even warns me that the printed expressions are always true.
You are using the term singleton incorrectly.
A singleton implies the existence of only one object of its own class. A Class object is an instance of the class java.lang.Class and there is more than one instance of this class. It’s actually impossible to have only one Class object, as the existence of a Class object does already imply the existence of at least two classes, java.lang.Object and java.lang.Class, so there must be at least two Class objects in the runtime.
Your example is not capable of spotting whether the class loader is well behaved or not. You already mentioned JLS §12.2
Well-behaved class loaders maintain these properties:
Given the same name, a good class loader should always return the same class object.
If a class loader L1 delegates loading of a class C to another loader L2, then for any type T that occurs as the direct superclass or a direct superinterface of C, or as the type of a field in C, or as the type of a formal parameter of a method or constructor in C, or as a return type of a method in C, L1 and L2 should return the same Class object.
A malicious class loader could violate these properties. However, it could not undermine the security of the type system, because the Java Virtual Machine guards against this.
Mind the last sentence. A JVM will guard against violations of these requirements. With the repeated occurrences of the same symbolic references within your example code, there are two possibilities
The JVM remembers the result of the first resolution of this symbolic reference within this context and just reuses it on the next occurrence without asking a class loader again.
The JVM remembers the result of the first resolution of this symbolic reference within this context and compares it with the result of subsequent resolutions of the same reference and throws an error if they mismatch.
Since both approaches imply remembering the result, the first approach is usually used when it comes to resolving the same reference within the same context, as it is simpler and more efficient. When it comes to different symbolic references that resolve to classes using the same reference, the JVM will indeed throw an error when the class loader constraints are violated.
So expressions like Main.class == Main.class or new Main().getClass() == new Main().getClass() will never evaluate to false. Most likely, the resolution of the symbolic reference to Main will go a short-cut, using the same runtime class regardless of what the class loader would do. But even when it does not take the short-cut and the ClassLoader is misbehaving, returning a different class object for the next query, the JVM would detect it and throw an error, so the expression would not evaluate to a boolean result at all. In neither case could it result in false.
In a single classloader, the Class object is the same.
Is the class loader always 'well-behaved' and why (not)?
It really depends on the implementation. If it is done deliberately that always the classloader always returns a new Class-Object, it won't be well-behaved.
At least all classloaders of OpenJDK are well-behaving.
In other words: are Class instances singleton? The other way around: can a Class of the same type be a different instance?
In one single classloader, every Class instance is a singleton. With multiple classloaders, following will evaluate to false:
ClassLoaderA.getInstance().loadClass("foo.Bar")==ClassLoaderB.getInstance().loadClass("foo.Bar");
The other way around: can a Class of the same type be a different instance?
Only if loaded by two different, conforming,well-behaved classloaders.
As a side-step, but by no means the main question: because the singleton pattern's legitimate uses are point of debate, would Java's Class be a good candidate to apply the singleton pattern to?
This is quite opinion-based, but I think, it's no good candidate to apply the singleton pattern, as most singletons are implemented like this:
class Foo{
public static final Foo INSTANCE=new Foo();
private Foo(){
ìf(INSTANCE!=null)
throw new IllegalAccessException("No Foo instances for you!");
}
}
So more that it is really ONE object of a Class, many that only differ by some small things like a different Classloader.
I made a small research on web and reviewed related topics on this site, but the answers were contradictory: some people said it is not possible, others said it is possible, but dangerous.
The goal is to pass an object of the anonymous class as a parameter of the RMI method. Due to RMI requirements, this class must be serializable. Here's no problem, it is easy to make class Serializable.
But we know that instances of inner classes hold a reference to an outer class (and anonymous classes are inner classes). Because of this, when we serialize instance of inner class, instance of outer class is serialized as well as a field. Here's the place where problems come: outer class is not serializable, and what's more important - I do not want to serialize it. What I want to do is just to send instance of the anonymous class.
Easy example - this is an RMI service with a method that accepts Runnable:
public interface RPCService {
Object call(SerializableRunnable runnable);
}
And here is how I'd like to call the method
void call() {
myRpcService.call(new SerializableRunnable() {
#Override
public Object run {
System.out.println("It worked!");
}
}
}
As you can see, what I want to do is to send an "action" to the other side - system A describes the code, that should be run on system B. It is like sending a script in Java.
I can easily see some dangerous consequences, if this was possible: for example if we access a field or captured final variable of outer class from Runnable - we'll get into a trouble, because caller instance is not present. On the other hand, if I use safe code in my Runnable (compiler can check it), then I don't see reasons to forbid this action.
So if someone knows, how writeObject() and readObject() methods should be properly overriden in anonymous class OR how to make reference to outer class transient OR explain why it is impossible in java, it will be very helpful.
UPD
Yet another important thing to consider: outer class is not present in the environment that will execute the method (system B), that's why information about it should be fully excluded to avoid NoClassDefFoundError.
You could try making Caller.call() a static method.
However, the anonymous class would still need to be available in the context in which you deserialize the serialized instance. That is unavoidable.
(It is hard to imagine a situation where the anonymous class would be available but the enclosing class isn't.)
So, if someone can show, how I can properly override writeObject and readObject methods in my anonymous class ...
If you make Caller.call() static, then you would do this just like you would if it was a named class, I think. (I'm sure you can find examples of that for yourself.)
Indeed, (modulo the anonymous class availability issue) it works. Here, the static main method substitutes for a static Classer.call() method. The program compiles and runs, showing that an anonymous class declared in a static method can be serialized and deserialized.
import java.io.*;
public class Bar {
private interface Foo extends Runnable, Serializable {}
public static void main (String[] args)
throws InterruptedException, IOException, ClassNotFoundException {
Runnable foo = new Foo() {
#Override
public void run() {
System.out.println("Lala");
}
};
Thread t = new Thread(foo);
t.start();
t.join();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(foo);
oos.close();
Foo foofoo = (Foo) new ObjectInputStream(
new ByteArrayInputStream(baos.toByteArray())).readObject();
t = new Thread(foofoo);
t.start();
t.join();
}
}
Another important thing to remember about: the Caller class is not present in the environment, that executes the method, so I'd like to exclude all information about it during serialization to avoid NoClassDefFoundError.
There is no way to avoid that. The reason that deserialization in the remote JVM is complaining is that the class descriptor includes a reference to the outer class. The deserializing side needs to resolve that reference even if you managed to clobber the reference, and even if you never explicitly or implicitly used the synthetic variable in the deserialized object.
The problem is that the remote JVM's classloader needs to know the type of the outer class when it loads the classfile for the inner class. It is needed for verification. It is needed for reflection. It is needed by the garbage collector.
There is no workaround.
(I'm not sure if this also applies to a static inner class ... but I suspect that it does.)
Attempting to serialize anonymous Runnable instance without outer class refers not only to a serialization problem, but to a possibility of arbitrary code execution in another environment. It would be nice to see a JLS reference, describing this question.
There is no JLS reference for this. Serialization and classloaders are not specified in the JLS. (Class initialization is ... but that is a different issue.)
It is possible to run arbitrary code on a remote system via RMI. However you need to implement RMI dynamic class loading to achieve this. Here is a reference:
http://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/guide/rmi/spec/rmi-arch.doc.html#280
Note that adding dynamic class loading for remote classes to RMI introduces significant security issues. And you have to consider issues like classloader leaks.
If you mad enough to do the trick you can use reflection to find field that contains reference to outer class and set it to null.
Your example as stated above cannot work in Java because the anonymous inner class is declared within class Caller, and you explicitly stated that class Caller in not available on the RPC server (if I understood that correctly). Note that with Java RPC, only data is sent over the network, the classes must already be available on the client and the server. It that respect your example doesn't make sense because it looks like you want to send code instead of data. Typically you would have your serializable classes in a JAR that is available to the server and the client, and each serializable class should have a unique serialVersionUID.
You can't do exactly what you want, which is to serialize an anonymous inner class, without also making its enclosing instance serializable and serializing it too. The same applies to local classes. These unavoidably have hidden fields referencing their enclosing instances, so serializing an instance will also attempt to serialize their enclosing instances.
There are a couple different approaches you can try.
If you're using Java 8, you can use a lambda expression instead of an anonymous inner class. A serializable lambda expression does not (necessarily) have a reference to its enclosing instance. You just need to make sure that your lambda expression doesn't reference this explicitly or implicitly, such as by using fields or instance methods of the enclosing class. The code for this would look like this:
public class Caller {
void call() {
getRpcService().call(() -> {
System.out.println("It worked!");
return null;
});
}
(The return null is there because RPCService.Runnable.run() is declared to return Object.)
Also note that any values captured by this lambda (e.g., local variables, or static fields of the enclosing class) must also be serializable.
If you're not using Java 8, your next best alternative is to use a static, nested class.
public class Caller {
static class StaticNested implements RPCService.Runnable {
#Override
public Object run() {
System.out.println("StaticNested worked!");
return null;
}
}
void call() {
getRpcService().call(new StaticNested());
}
}
The main difference here is that this lacks the ability to capture instance fields of Caller or local variables from the call() method. If necessary, these could be passed as constructor arguments. Of course, everything passed this way must be serializable.
A variation on this, if you really want to use an anonymous class, is to instantiate it in a static context. (See JLS 15.9.2.) In this case the anonymous class won't have an enclosing instance. The code would look like this:
public class Caller {
static RPCService.Runnable staticAnonymous = new RPCService.Runnable() {
#Override
public Object run() {
System.out.println("staticAnonymous worked!");
return null;
}
};
void call() {
getRpcService().call(staticAnonymous);
}
}
This hardly buys you anything vs. a static nested class, though. You still have to name the field it's stored in, and you still can't capture anything, and you can't even pass values to the constructor. But it does satisfy your the letter of your initial question, which is how to serialize an instance of an anonymous class without serializing an enclosing instance.
The answer is no. You cannot do that since Inner class will need outer class to be serialized. Also you would run into troubles when you'd try to call the instance method of the outer class within the inner class. Why don't you just have another top level class which you could send?
I'd like to add to this topic. There is a way to achieve what you want, but will require reflection.
Here is a good tutorial on implementing a custom serializable object using writeObject and readObject
And here is a good tutorial (website font is kind of an eyesore, but the content is worth it) on on how Reflection is used to for serialization. The tutorial refers to final fields, but applies to any field.
You'll have to use Reflections getDeclaredField
This question already has answers here:
Singleton class with several different classloaders
(2 answers)
Closed 9 years ago.
I was designing the below singleton class, and I am aware of that where my singleton can be broken
public class SingletonObject {
private static SingletonObject ref;
private SingletonObject () //private constructor
{ }
public static synchronized SingletonObject getSingletonObject()
{
if (ref == null)
ref = new SingletonObject();
return ref;
}
public Object clone() throws CloneNotSupportedException
{throw new CloneNotSupportedException ();
}
}
the following url already suggest where singleton can be broken cracking singleton with other ways but my query is that as suggested in this url that singleton can be broken by class loader also same class could be loaded by two different class loaders, as such, you could create two instances of your singleton class by simply invoking its getInstance() method in a class loaded by two different class loaders. This approach would work without having to resort to violating the private constructor.
ClassLoader cl1 = new URLClassLoader(new URL[]{"singleton.jar"}, null);
ClassLoader cl2 = new URLClassLoader(new URL[]{"singleton.jar"}, null);
Class<?> singClass1 = cl1.loadClass("hacking.Singleton");
Class<?> singClass2 = cl2.loadClass("hacking.Singleton");
//...
Method getInstance1 = singClass1.getDeclaredMethod("getInstance", ...);
Method getInstance2 = singClass2.getDeclaredMethod("getInstance", ...);
//...
Object singleton1 = getInstance1.invoke(null);
Object singleton2 = getInstance2.invoke(null);
Please advise what measure should be taken to avoid this also.
If you want to create true singleton, you should avoid using custom classloaders - all singletons should be loaded by common parent classloader.
Example of resolving your issue from question, linked below:
private static Class getClass(String classname) throws ClassNotFoundException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader == null)
classLoader = Singleton.class.getClassLoader();
return (classLoader.loadClass(classname));
}
Similar questions:
Singleton class with several different classloaders
This is the scenario you are worried about:
Classloader A does not have Singleton on its classpath.
Classloader B is a child classloader of A and has Singleton on its classpath.
Classloader C is a child classloader of A and has Singleton on its classpath.
Both B and C load Singleton.
When this happens you end up with two distinct types called Singleton ... according to the JLS. So when you create the respective instances, they will be instances different types. (Arguably, the "one of a type" invariant has not been broken because the types are not the same. However, if the purpose of the singleton is to hold state that must be held only once, that technical argument is beside the point.)
And in fact, if you do end up with that situation, then another class loaded by B won't be able to use A's instance of Singleton ... or vice versa ... because of the different types. Effectively B's and C's sets of classes will only "know" about one of the singleton instances ... respectively.
Anyway, if you really do need B's and C's classes to share one instance of Singleton, the way to achieve it is to put Singleton onto the classpath of a common parent/ancestor classloader; e.g. A in this case.
Please advise what measure should be taken to avoid this also.
On re-reading this, it seems that you are looking for a way stop someone else from writing code that accidentally or deliberately breaks the invariant using a classloader.
I don't think there is one ... unless you treat other people's code as untrusted and run it inside a sandbox that prevents them creating classloaders, using abstraction-breaking reflection, and so on.
I don't think it should be a concern, since classes loaded by different loaders are incompatible, and you will not be able to cast both instances to SingletonObject.
To avoid such situation Singleton's class should be loaded by the top most class loader. In such complex case this should be done at application start up, before any other class loader appear. Invoke getSingletonObject() method first to load class and instatantiate singleton. Child class loaders (home made, for exmple) in tern should not break class loading policy: first look up class at parent class loader and only then try to load itself. If the break, multiple Singletons can appear.
I am new to Java. One thing confuses me is to why some of the classes need new to instantiate, and why some others do NOT need new to instantiate.
For example, I am looking at log4j, it does not need new.
// get a logger instance named "com.foo"
Logger logger = Logger.getLogger("com.foo");
logger.setLevel(Level.INFO);
Why do some other classes need new? For example, an Employee class:
Employee X = new Employee (John);
X.getwork();
etc etc.
Why we did not say , Logger logger = new Logger(...);? and why were we able to use it even without new, like logger.setLevel(), etc.
The only way to create a new object in Java is with new [1]. However, in some classes, you're not permitted to say new for yourself, you must call a factory method, which might be static (as with your logger example) or not. The author of a class sets this up by making the constructor(s) have access other than public.
Also note that your example may not involve a new object at all. That Logger function might be returning an old object, not a new one.
The following poem by Ogden Nash seems faintly relevant:
This morning I went to the zoo
In order to look at the gnu.
But the old gnu was dead,
and the new gnu, they said,
Was too new a new gnu to view.
[1] Unless you get involved in low-level reflection, or use Object.clone()
In this case, we are dealing with factory methods, as I stated in my comment.
See the relevant API specification on Logger
Retrieve a logger named according to the value of the name parameter. If the named logger already exists, then the existing instance will be returned. Otherwise, a new instance is created.
By default, loggers do not have a set level but inherit it from their neareast ancestor with a set level. This is one of the central features of log4j.
The factory method pattern is a creational design pattern, and, according to Wikipedia, is often useful in the following situations:
The factory pattern can be used when:
The creation of an object precludes its reuse without significant duplication of code.
The creation of an object requires access to information or resources that should not be contained within the composing class.
The lifetime management of the generated objects must be centralized to ensure a consistent behavior within the application.
All three of these are applicable here... who knows what kind of work goes into finding the correct logger? You're not really interested in creating a brand new logger each time you want to use one... instead, your focus is mainly just that -- to use one.
The Creative Commons Wiki also has a relevant article,
Factory methods are sometimes used in place of constructors for any of several reasons:
Some languages (such as Java) do not allow constructors to have useful names
Some languages (such as Java) do not allow constructors to have different names (which may be necessary if you want to use the same method signature for two constructors)
To allow the same instance to be reused instead of recreated each time it is needed (see FlyweightPattern)
I think the third option is probably the most applicable here. Using manual creation of a new Logger, you are unable to adequately share them. Using the getLogger facade enables this to happen transparently.
All in all, the use of factory methods is usually to enable cleaner more straight-forward code without exposing work you don't necessarily care about.
For instance, some classes may prevent you from creating more than one object in the application. It that case you need to call some method for instantiate the class, like the Logger.getLogger(). The getLogger() may have the code like this:
if(uniqueInstance == null) {
uniqueInstance = new Logger();
}
return uniqueInstance;
Where uniqueInstance is an instance of Logger. This is a design pattern called Singleton. In this pattern, you can't instantiate the class because it's constructor is private.
Some other way that you can't instantiate a class is when the class is defined as static.
Classes that have public constructors and aren't static need to be instantiated with the new keyword.
because Logger.getLogger() returns a Logger object. new Logger() calls the constructor which also returns a Logger. This also kind of uses new too, because inside the Logger class is probably something like:
public class Logger {
public static Logger getLogger() {
return new Logger("foo", "bar");
}
}
Well what you are asking is more related to design patterns. The Logger class is following singleton pattern.
Suppose you want that only a single instance of your class gets created accross the application then you can make your constructor private and provide a static method which creates and stores the object of your class when invoked for the first time.
public class SingletonPattern{
private static SingletonPattern instance;
private SingletonPattern(){}
public static synchronized SingletonPattern getInstance(){
if (instance == null){
instance = new SingletonPattern();
}
return instance;
}
}
In this way you can restrict your class to be instantiated only once.
In your example you have to different use cases : the static method that returns an object and the actual constructor call.
The static method is a method that doesn't need to be call on a object, here it's inner mechanism may instantiate an object and return it for futur usage, in this method, there's a call to "new" but the object might be configured, or retrieved from a cache before being return. This is this kind of call
Logger logger = Logger.getLogger("com.foo");
The actual constructor call (which use new) is the normal way to create new object.
You were not technically using the Logger class, but were using a method. You were not technically instantiating the Logger class, nor keeping a reference to it directly as you would with Logger logger = new Logger(). Instead, what you are doing is accessing a method to get back a returned instance. It would be nice to see the class definition. However, more than likely what you have is a static method inside of the class. And the class is more than likely defined with a private constructor. This allows the methods to be accessed without instantiating the class. You can see a good explanation of this, and of static in java here: https://stackoverflow.com/a/1844388/1026459
Some classes cannot be instantiated outside of themselves (e.g. the Math class, these classes have non-public constructors). Of those classes, some provide methods that return instances of the class (e.g. the InetAddress class). These are called factory methods. They are static methods that return instances of the class they're in, so the new keyword need not be used (it is instead used inside of the factory methods). For example:
public class A {
private A() {}
public A createAnA() { return new A(); }
}
Here, createAnA() is the factory method.
I'm working with an abstract class and a (growing) set of subclasses of this class. For certain reasons all subclasses of A should implement the singleton pattern. During startup of the application there exists a List<Class<? extends A>> and I would like to initialize all singleton-instances.
From what I see, my option here is to go for Reflection, enforcing by guidelines that all A-implementing classes have to have a defined constructor and invoke that via o.getDeclaredConstructor().newInstance();.
I've also tried a different approach where I used overloading of static methods. That is, A defined a static initialize method and all subclasses had to reimplement that method. The call can again be invoked via reflection.
The first approaches has the obvious disadvantage that violations of the programming-guideline result only in runtime-errors, not in compile-time errors. The second is even worse, if a subclass does not implement the static method, only the method in A is called with no apparent exception thrown.
So: How do I enforce a uniform way to initialize in a set of singleton classes?
Edit:
A configuration-class generates a list of all children of A during startup, those classes can be either registered directly in the configuration class programmatically or configured via a configurationfile:
private void initModules() {
Configurator.addModule("modulename", SubOfA.class);
...
}
private void initModuleFile() {
...
String name = in.readLine();
String classname = ...;
String modulename = ...;
Configurator.addModule(modulename, Class.forName(classname));
}
those classes can be [...] configured via a configurationfile
In this case the common approach is like your first proposal: Class.forName("...").newInstance()
(This can, of course, be encapsulated by some kind of factory pattern.)
Since, in Java, you cannot enforce a particular constructor to be implemented by subclasses, the only viable way is to demand a default constructor by design guidelines/contracts.
As an example, have a look at Android's Parcelable:
Classes implementing the Parcelable interface must also have a static
field called CREATOR, which is an object implementing the
Parcelable.Creator interface.