Singleton class, between different classloader and thread [duplicate] - java

E.g I have class Singleton with static field instance:
public class Singleton {
private static Singleton instance;
// other code, construct, getters, no matter
}
I can load this class twice with two different classloaders. How could I avoid it? It is unsafe and dangerous.
Also, if I set instance to null, would it set to null for both classes?
Singleton singleton = Singleton.getInstance();
singleton = null;

If you want a true Singleton across classloaders, then you need a common parent to load the class in question, or you need to specify the classloader yourself.
Update: From the comment from #Pshemo below a fair bit of the content in the blog below might come directly from a JavaWorld Article. I've left the blog entry in as it may still help someone, but its worth knowing where the content originally came from.
Original:
There is a blog entry that gives you a way to do this" (although I havent tried it!), and it looks fairly reasonable
As requested below here a code snippet from my link above - I do suggest you visit the blog though for the full context:
private static Class getClass(String classname) throws ClassNotFoundException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader == null)
classLoader = Singleton.class.getClassLoader();
return (classLoader.loadClass(classname));
}

This is a hack misusing the fact that Properties extends Map, an old unfortunate design decision.
public final class JvmWideSingleton
{
private static final JvmWideSingleton INSTANCE;
static {
// There should be just one system class loader object in the whole JVM.
synchronized(ClassLoader.getSystemClassLoader()) {
Properties sysProps = System.getProperties();
// The key is a String, because the .class object would be different across classloaders.
JvmWideSingleton singleton = (JvmWideSingleton) sysProps.get(JvmWideSingleton.class.getName());
// Some other class loader loaded JvmWideSingleton earlier.
if (singleton != null) {
INSTANCE = singleton;
}
else {
// Otherwise this classloader is the first one, let's create a singleton.
// Make sure not to do any locking within this.
INSTANCE = new JvmWideSingleton();
System.getProperties().put(JvmWideSingleton.class.getName(), INSTANCE);
}
}
}
public static JvmWideSingleton getSingleton() {
return INSTANCE;
}
}
This could be made parametrized, but then the initialization would be lazy and go to getSingleton().
Properties is Hashtable-based, so it is thread safe (as per the documentation). So one could use props.computeIfAbsent(). But I like it this way more.
Also read here: Scope of the Java System Properties
I just wrote it and there is a chance there's something I overlooked that would prevent this from working.

Related

Why enum singleton is lazy?

I saw answers like these, tried to clarify via comments, and was unsatisfied by examples here.
Maybe it's time for this specific question...
Why enum singleton implementation is called lazy?
public enum EnumLazySingleton {
INSTANCE;
EnumLazySingleton() {
System.out.println("constructing: " + this);
}
public static void touchClass() {}
}
How it is different from eager implementation?
public class BasicEagerSingleton {
private static final BasicEagerSingleton instance = new BasicEagerSingleton();
public static BasicEagerSingleton getInstance() {
return instance;
}
private BasicEagerSingleton() {
System.out.println("constructing: " + this);
}
public static void touchClass() {}
}
Both will init instance without accessing INSTANCE/getInstance() - e.g. call touchClass().
public class TestSingleton {
public static void main(String... args) {
System.out.println("sleeping for 5 sec...");
System.out.println("touching " + BasicEagerSingleton.class.getSimpleName());
BasicEagerSingleton.touchClass();
System.out.println("touching " + EnumLazySingleton.class.getSimpleName());
EnumLazySingleton.touchClass();
}
}
Output:
sleeping for 5 sec...
touching BasicEagerSingleton
constructing: BasicEagerSingleton#7bfcd12c
touching EnumLazySingleton
constructing: INSTANCE
Now, we can say both are lazy. What is eager then?
It is clear how (e.g) "double-checked locking" way is actually lazy (and messy, and slow). But if enum is lazy, then any singleton is lazy due to inevitable class loading - in fact, everything is lazy. At which point will this distinction stop making any sense?
The first two linked answers (by Peter Lawrey and Joachim Sauer) both agree that enums are not lazily initialized. Answers in the third link are simply wrong about what lazy initialization means.
The recommendation to use enums as singletons originates from Josh Bloch's Effective Java. Notably, the chapter on enum singletons makes no mention of laziness. There is a later chapter dedicated to lazy initialization, that likewise makes no mention of enums. The chapter contains two highlights.
If you need to use lazy initialization for performance on a static field, use the lazy initialization holder class idiom.
If you need to use lazy initialization for performance on an instance field, use the double-check idiom.
Undoubtedly, enums would be another idiom on this list if they were in any way lazily initialized. In fact they are not, although confusion about the meaning of lazy initialization results in some incorrect answers, as the OP shows.
May I wager the following:
You are trying to identify 2 "processes" or ... "things" (let's make this easy to understand - because if I start saying "Code Blocks", it sounds more difficult)...
At some point the class-loader will run, and you would like to know what "things" will be executed when the class-loader loads a class.
At another point invoking a method on the class will cause another "thing" to run / execute, and you would like to know which, exactly, (which "processes") would start..
The following facts are relevant:
Static initializers are run when the class-loader loads the class. The class-loader will not load the class until the code that is
running encounters the need to load it (because a method or field has
been invoked) such as: touchClass()
If a singleton instance of EITHER a class, OR an enumerated type has a field that is being initialized in the static
part of the class it will be loaded as soon as you 'touch' the
class - because the Class-Loader runs all static initializations for a class or enum on loading.
Lazy loading, likely, (And this is my "interpretation" about what you are asking) would happen when a method invokation asks the class
to create a singleton instance - which could happen quite a bit of
time after the "loading" of the class or enum.
A class like the following:
public class LazySingleton
{
// At time of class-loading, this singleton is set to 'null'
private static singleton = null;
// This is a method that will not be invoked until it is called by
// some other code-block (some other "thing")... When "touchClass()"
// is called, the singleton instance is not created.
public static LazySingleton retrieveSingleton()
{
if (singleton == null) singleton = new LazySingleton();
return singleton;
}
// DOES NOTHING... The Singleton is *not* loaded, even though the
// Class Loader has already loaded this Java ".class" file
// into memory.
public static void touchClass() { }
private LazySingleton()
{ System.out.println("constructing: LazySingleton"); }
}
Here on the other hand:
public enum EagerEnum
{
// The class loader will run this constructor as soon as this 'enum'
// is loaded from a '.class' file (in JAR or on disk) into memory
MyEnumConstant();
private EagerEnum()
{ System.out.println("Eager Enum Constructed"); }
// This will cause the Class Loader to Load this enum from the
// Java ".class" File immediately, and the "MyEnumConstant" will
// also have to be loaded - meaning the constructor will be called.
public static void touchEnum() { }
}
So the following code would produce the output
LazySingleton.touchClass(); // Prints nothing
EagerEnum.touchClass(); // Prints "Eager Enum Constructed"
LazySingleton.getSingletonInstance(); // Prints "constructing: LazySingleton

Use of properties across multiple classes

My question is the same as this one except it is for Java, specifically applied to properties. Ideally I would like to create one instance of Properties, and call the methods from all of the classes without creating new instances. I would also want to read from a single instance of properties so I only have a single source of the truth.
I have read the API for Properties and it doesn't answer my question.
This question indicates I need to include the reference in the class constructor. Is there a better way??
The fisrt link, "this one" is a link to the Oracle documentation...
If you want to load your properties only once, you should use the singleton pattern. But be carefull that this pattern can be an anti-pattern and may make your unit tests more complex.
To avoid those drawbacks it is better to pass the reference to your properties via a constructor.
/* This is your singleton. It takes care of loading the properties only once and can delegate access method to it */
public class Configuration {
private static Configuration instance; // created only once
public static getInstance() {
instance = // Read the Singelton pattern to create it only once
}
private Properties properties; // loaded only once
public String get(String key) {
return properties.getProperty(key);
}
}
public class Component {
private final Configuration cfg;
public Component (Configuration cfg) {
this.cfg = cfg;
}
}
public class StarterOrDiContainer {
// ..
Component component = new Component(cfg.getInstance());
}
Let's take the system properties as example. In this implementation http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/System.java#System.getProperty%28java.lang.String%29, the properties are just stored in a static class attribute. Either make this attribute public or create public accessor methods. Short answer: just make it static.
You can initialize static data with static initializers, if things get a little bit more complex. (https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html)

Java - Singleton usage with multiple class loaders

I have a simple singleton class in Java that looks like the following one:
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
public void doSomething(){
...
}
}
My code also contains two classes, from now on called A and B, that both have the following structure:
public class Foo{
...
public void bar(){
...
Singleton.getInstance().doSomething();
...
}
...
}
During an execution the code in class A is executed first and therefore it silently instantiates the singleton instance. However, later on when B's code gets executed, the singleton instance is instantiated again, which is not what I want to achieve.
After a little investigation we found that class A and B use a different class loader, which means the singleton class is also loaded twice, resulting into two singleton instances.
I've looked for solutions to this issue on the web and found several (quite similar) pages, e.g. http://www.javaworld.com/article/2073352/core-java/simply-singleton.html?page=2 and http://snehaprashant.blogspot.nl/2009/01/singleton-pattern-in-java.html.
However, after trying out several options I still can't get it to work, mainly because I don't really know how to apply the solution(s) in the simple code listed above.
So my question is: can someone provide me with a (clue to a) practical solution for my code to the problem described above so that the singleton is only instantiated once regardless of the classloader being used?
I doubt the solution in the JavaWorld article works. getContextClassLoader(), and Singleton.class.getClassLoader() can return different classloaders each time. And if you got a consistent classloader, then the only way to use the class would be via reflection.
I guess they expect you to replace:
Singleton.getInstance().doSomething();
with:
try {
Object instance = getClass("package.Singleton").getMethod("getInstance").invoke(null);
instance.getClass().getMethod("doSomething").invoke(instance);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
Instead, I would look at why there are multiple classloaders. Either keep all your code under the same classloader, or put the singleton into a common parent of both classloaders, and make the class unavailable to the child classloaders.

Understanding Props for actor creation

I'm trying to undersatnd how to use Props correctly. My first thought was that Props objects contain some property of the actor being created. These properties might include the actor's field values as well as some deployment related information (e.e.g which dispatcher to use). The later has nothing to do with the actual actor and therefore should be shipped independent.
But in the documentation said the the good practice is to use static factory method within the actor like this (documentation removed):
public class DemoActor extends UntypedActor {
public static Props props(final int magicNumber) {
return Props.create(new Creator<DemoActor>() {
private static final long serialVersionUID = 1L;
#Override
public DemoActor create() throws Exception {
return new DemoActor(magicNumber);
}
});
}
}
I think this is not quite good if for instance we want to use one dispatcher now, and the requirements will change at some point in the future. It will lead to modifying the Actor class which is (in my opinion) incorrect.
The static factory method, I believe, may be particularly useful for Java, which tends to get quite verbose with Akka. While the code you've shown is for the Actor class, you will also usually have some Inversion-of-Control style configuration or bootstrapper class where you typically set up the actor system and then the actors with the ActorSystem#actorOf class.
Now, after retrieving the base Props instance from the Actor's props factory method you can configure it a bit to your purposes (Props is immutable but have methods returning modified instances). In case you need a different dispatcher then you will just modify your bootstrapper class from something like this:
ActorSystem system = ...;
system.actorOf(DemoActor.props(42), "demo-with-default-dispatcher");
to:
system.actorOf(DemoActor.props(42).withDispatcher("DemoDispatcher"), "demo-with-configured-dispatcher");
(these are just minimal code snippets but I think you get the idea)

Initialize a "singleton" by configure file is suitable or not?

Initialize a singleton by configure file is suitable or not?
I notice that the constructor of singleton should not have any parameter, the reason is that if you need use parameters to configure your object, probably that should not be singleton. Seems this sentence very famous, but indeed there are serval cases are special:e.g.
We design a simple distributed system to deal with tons of users' query:
only one central server
n sub servers, each sub server connecting to central server
there is no connections between sub servers
Obviously, we may design the "central server" as singleton, the details like this:
enum ServerType;
abstract class Server;
class CentralServer inherit from Server;(CentralServer is singleton)
class SubServer inherit from Server;
class Query;
... ... ...
But the central server need some configuration, such as:
serverName
description
portNum-ipAddress map
the list of its sub servers
the size of BlockingQueue
... ... ...
How to initialize the central server by these properties?
My current solution:
using the configure file to finish this part job.
I define another class called Configuration.
So the current constructor of central server like this:
class CentralServer extends Server implements Runnable, ....... {
....
....
private static CentralServer _instance;
private CentralServer () {
super();
....
serverName = Configuration.getCentralServerName();
description = Configuration.getCentralServerDescription();
Configuration.initCentralServerPortNumIpMap(portNumIpMap);
Configuration.initCentralServerSubServersList(subServersList);
sizeBlockingQueue = Configuration.initCentralServerBlockingQueueSize();
....
}
public CentralServer getInstance() {
if (_instance == null) {
_instance = new CentralServer();
}
return _instance;
}
....
....
}
The Configuration class, will read and analyze configuration-file, to get out of configuration info.
My Question:
Initialize singleton like this suitable or not, if not, please
give out more suitable approach
I also need configure all sub servers, so seems the Configuration
class is too heavy, should I split the Big Configuration class into
two sub class? class CentralConfiguration, and class
SubConfiguration?
Unfortunately, your implementation for a Singelton is WRONG!! Simply because it is not thread safe.
public CentralServer getInstance() {
if (_instance == null) { // race condition possible here
_instance = new CentralServer();
}
return _instance;
}
Two threads might enter this critical section and evaluate _instance==null to true, and two different instances will be created.
You can simply instantiate your instance statically.
private final static CentralServer INSTANCE = new CentralServer();
public static CentralServer getInstance() {
return INSTANCE;
}
However, the best way to implement singeltons is to use enums
public enum CentralServer { // the best way to implement singletons, due to the author of Effective Java
INSTANCE;
private CentralServer() {
}
}
This gives you serialisation for free.
However, I dont think that you need a singelton at all, singeltons are usually Anti patterns.
Check this out.
In your code, CentralServer has a high dependency on Configuration which I don't think is a good thing, you should see Configuration as a dependency
class CentralServer{
private final Configuration serverConf;
private CentralServer(Configuration serverConf){ // inject configuration
this.serverConf = serverConf;
}
public static CentralServer createCentralServer(Configuration serverConf){ // static factory perhaps
return new CentralServer(serverConf);
}
}
This will give you more flexibility to change or mock configuration. I think Factory pattern would be more appropriate here.
It is perfectly acceptable to make use of external resources during the initialization of your singleton. A common user of the Singleton pattern is loggers and they are almost always configured from external data files.
It does make initialization more complicated but it is not impossible to make a fully tread-safe singleton that accesses external resources such as configuration files. They can even make use of other singletons such as connection pools if their configuration requires database access.
The other answers to this question correctly deal with the actual problems with your singleton initialization.
Initialize singleton like this suitable or not, if not, please give
out more suitable approach:
It is not a suitable approach, because the implementation is not threadsafe yet and it can be broken f.e. via reflection. You should consider reading Effective Java by Joshua Bloch on this topic.
Better would be to create an enum singleton, because this approach is more flexible for later changes, has threadsafe instanciating and is unbreakable.
EDIT: example .
I also need configure all sub servers, so seems the Configuration
class is too heavy, should I split the Big Configuration class into
two sub class? class CentralConfiguration, and class SubConfiguration?
For configuration purposes, there is usually a config.xml file or a config.properties file somewhere to read important preconfigurations. After creating an instance, you should extract the information from such a file and write out necessary changes when shutting down. But as always, many ways lead to rome.

Categories

Resources