I follow this post to create a thread safe singleton classs, but there is an compile error in INSTANCE. It said The blank final field INSTANCE may not have been initialized. My requirement is I want INSTANCE is null and the program log this error and try init this object again. If still fail, the program exit.
public class ServiceConnection {
private static class SingletonObjectFactoryHolder{
private static final ServiceSoapBindingStub INSTANCE;
static
{
try {
INSTANCE = new ServiceSoapBindingStub();
} catch (AxisFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static ServiceSoapBindingStub getInstance() {
return SingletonObjectFactoryHolder.INSTANCE;
}
}
But If I use the Code as follows, another error: The final field INSTANCE may already have been assigned
public class ServiceConnection {
private static class SingletonObjectFactoryHolder{
private static final ServiceSoapBindingStub INSTANCE;
static
{
try {
INSTANCE = new ServiceSoapBindingStub();
} catch (AxisFault e) {
INSTANCE = null;
e.printStackTrace();
}
}
}
public static ServiceSoapBindingStub getInstance() {
return SingletonObjectFactoryHolder.INSTANCE;
}
}
But If I use the Code as follows no error pop up.
public class ServiceConnection {
private static class SingletonObjectFactoryHolder{
private static final ServiceSoapBindingStub INSTANCE;
static
{
try {
INSTANCE = new ServiceSoapBindingStub();
} catch (AxisFault e) {
e.printStackTrace();
throw new RuntimeException();
}
}
}
public static ServiceSoapBindingStub getInstance() {
return SingletonObjectFactoryHolder.INSTANCE;
}
}
Why this happens?
Given what you've said, you shouldn't be using class initialization for this. In particular:
You want to try multiple times
You want to use a checked exception
Both of those are feasible, but you'll need to move the initialization into the getInstance method:
public class ServiceConnection {
private static final Object lock = new Object();
private static ServiceSoapBindingStub instance;
public static ServiceSoapBindingStub getInstance() throws AxisFault {
// Note: you could use double-checked locking here if you really
// wanted.
synchronized (lock) {
if (instance == null) {
instance = new ServiceSoapBindingStub();
}
return instance;
}
}
}
(You can catch the exception to log it and then rethrow, of course - but consider whether a higher level would be logging it anyway.)
Related
The unit test of a class is involved with a static method in a another class, say HelperClass. HelperClass has a singleton member. I used Junit for the unit tests and Powermockito to mock the singleton member. But I found that the behavior of the method of the singleton member can only be specified once.
//the class to be tested
class Activity {
public void enact() {
//some logic
String str = HelperClass.doSomething();
//some other logic
}
}
class HelperClass {
private static final singleton = Singleton.getInstance();
public static String doSomething() {
//some logic
AnObject obj;
try {
obj = singleton.doSomething();
} catch (Exception1 e) {
//Some other logic
throw new Exception2("Some message" + e.getMessage(), e);
}
String val = obj.doSomething();
return val;
}
}
class Singleton {
private Singleton instance = null;
private void Singleton() { /*some logic*/ }
public static Singleton getInstance() {
if (instance == null) {
Singleton();
}
return instance;
}
public String doSomething() throws Exception1 {
//some logic
}
}
My uint test goes like this
#RunWith(PowerMockRunner.class)
#PrepareForTest(Singleton.class)
class ActivityTest {
//some logic
private Activity activity;
#Before
public void setup() {
//some logic
PowerMockito.mockStatic(Singleton.class);
activity = new Activity();
}
#Test(expected = Exception2.class)
void test1() {
Singleton mockSingleton = mock(Singleton.class);
when(mockSingleton.doSomething()).thenThrow(new Exception1("Test Exception1"));
PowerMockito.when(Singleton.getInstance()).thenReturn(mockSingleton);
activity.enact();
}
#Test
void test2() {
Singleton mockSingleton = mock(Singleton.class);
when(mockSingleton.doSomething()).thenReturn("");
PowerMockito.when(Singleton.getInstance()).thenReturn(mockSingleton);
activity.enact();
}
}
But it does not work. Although I specify different behaviors of the doSomething() of the mockSingleton, the mockSingleton still throws the Exception2 in test2 as it does in test1. It seems that the behavior can only be specified once. Can somebody tell me how I can let the doSomething() here have different behaviors?
You are calling Signleton.getInstance only once - when HelperClass is initialized. This way you always use the mock from your first test. To solve this, you can call getInstance every time you need an instance of Singleton.
Thus, the code for HelperClass would be:
class HelperClass {
public static String doSomething() {
//some logic
AnObject obj;
try {
obj = Singleton.getInstance().doSomething();
} catch (Exception1 e) {
//Some other logic
throw new Exception2("Some message" + e.getMessage(), e);
}
String val = obj.doSomething();
return val;
}
}
This way, you will get the right mock on every run.
Singleton is a service that require injection of authentication and configuration data. I end with class:
class SingleService {
private String conn;
private String user;
private String pass;
private SingleService() {
// Can throw exception!!
conn = Config.getProperty("conn");
user = Config.getProperty("user");
pass = Config.getProperty("pass");
// Can throw exception!!
internalService = tryConnect(conn, user, pass);
}
private static SingleService instance;
public static void init() {
instance = new SingleService();
}
public static synchronized SingleService getInstance() {
if (instance == null) init();
return instance;
}
}
Dedicated init() method used for exception handling during application startup to early detect initialization errors early because later we just call getInstance() and doesn't expect to get errors:
class App {
public static void main(String args[]) {
try {
Config.init("classpath:auth.properties");
SingleService.init();
} catch (Exception ex) {
logger.error("Can't init SingleService...");
System.exit()
}
doJob();
}
private static void doJob() {
SingleService.getInstance().doJob();
}
}
I worry about init() method and singleton class signature. Fill that class was designed badly but don't understand what's wrong.
Is it possible to move away initialization from getSingleton() and synchronized and preserving control on exception during initialization?
This is how I would code it so you can throw exceptions if needed but still have a thread safe singleton.
enum SingleService {
INSTANCE;
private String conn;
private String user;
private String pass;
private SingleService instance;
public synchronized void init(Config config) throws SomeException {
// don't leave in a half state if we fail.
internalService = null;
conn = config.getProperty("conn");
user = config.getProperty("user");
pass = config.getProperty("pass");
internalService = tryConnect(conn, user, pass);
}
public synchronized void methodForService() {
if (internalService == null) throw new IllegalSateException();
// do work.
}
}
SingleService ss1 = SingleService.getInstance();
SingleService.init();
SingleService ss2 = SingleService.getInstance();
So ss1 is a different object than ss2 which is not what Singleton is designed for. If ss1 is modified at anytime ss2 will remain unaffected.
Fist of all you souhld not expose object creation method. If you want to check something, than go with asserts or any operation that will not corrupt instance object.
public static void checkIfValid() {
assert Config.getProperty("conn");// do not corrupt instance object
assert Config.getProperty("user");
assert Config.getProperty("pass");
}
public static synchronized SingleService getInstance() {
if (instance == null){ // only here you can initiate instance object
instance = new SingleService();
}
return instance;
}
My production code for problem I have sought:
public abstract class AbstractCaller<Port> {
abstract protected Port createPort();
protected init() {
Port port = createPort();
// heavy use of introspection/reflection on **port** object.
// Results are used later by **call** method.
}
public call() {
// Reflection based on data collected by **init** method.
}
}
public class ConcreteCaller extends AbstractCaller<ConcretePort> {
private ConcreteService service = new ConcreteService();
#Override
protected ConcretePort createPort() {
return service.getPort();
}
private static class Holder {
public static ConcreteCaller INSTANCE;
static {
INSTANCE = new ConcreteCaller();
INSTANCE.init();
}
}
public static Caller getInstance() {
return Holder.INSTANCE;
}
}
Abstract class has common init method that can only operate on fully initialized concrete class. Inner static class is used for lazy instantiation and perform init invocation.
There is no way to apply init method from superclass constructor to avoid need to call init in each implementation.
Below is my CuratorClient class which is connecting to Zookeeper and starting the leader election process as well.
public class CuratorClient {
// can I make this as static?
private static CuratorFramework client;
private String latchPath;
private String id;
private LeaderLatch leaderLatch;
public CuratorClient(String connString, String latchPath, String id) {
client = CuratorFrameworkFactory.newClient(connString, new ExponentialBackoffRetry(1000, Integer.MAX_VALUE));
this.id = id;
this.latchPath = latchPath;
}
public void start() throws Exception {
client.start();
client.getCuratorClient().blockUntilConnectedOrTimedOut();
leaderLatch = new LeaderLatch(client, latchPath, id);
leaderLatch.start();
}
public boolean isLeader() {
return leaderLatch.hasLeadership();
}
public Participant currentLeader() throws Exception {
return leaderLatch.getLeader();
}
public void close() throws IOException {
leaderLatch.close();
client.close();
}
// can I use below method from any other class ?
protected static List<String> getChildren(String node) throws Exception {
return client.getChildren().forPath(node);
}
}
When my service gets started up, in the static block I am making a connection to Zookeeper using CuratorClient and starting the leader election process as well.
public class TestService {
private static CuratorClient curatorClient = null;
static {
try {
String connectionString = "some-string";
String hostname = "machineA";
curatorClient = new CuratorClient(connectionString, "/my/latch", hostname);
curatorClient.start();
} catch (Exception ex) {
// log exception
}
}
....
....
// some method
public Map<String, String> installNewSoftware(String node) {
//.. some other code
try {
List<String> children = CuratorClient.getChildren("/my/example");
System.out.println(children);
} catch (Exception e) {
e.printStackTrace();
}
//.. some other code
return null;
}
}
Now I have some other class as well which likes to use the getChildren method of CuratorClient so in this class, I can directly use like this CuratorClient.getChildren("/my/example"); correct?
public class DifferentClass {
....
....
// some new method
public Map<String, String> installNewSoftware(String node) {
try {
List<String> children = CuratorClient.getChildren("/my/example");
System.out.println(children);
} catch (Exception e) {
e.printStackTrace();
}
//.. some other code
return null;
}
}
In general, this is not a curator question or zookeeper question. It's basically a design question and I am trying to understand whether the way I am doing it will have any problem or not? And I am assuming CuratorFramework will be thread safe as well?
Yes, you can call static methods from other classes.
Your signature looks like this:
protected static List<String> getChildren(String node) throws Exception
The reason you can't call this from another class is because it's protected (visible to the current class and subclasses) instead of public (visible to everywhere).
If you make it visible you can call it with CuratorClient.getChildren().
More information on access modifiers.
More information on class members (static fields).
I have an example code of Singleton class inheritance below. However, I've not forseen if there's any hidden issue might happen with this code. Can someone analyze and give me a hint?
interface ChairIF {
public int getLeg();
public void test();
}
class ChairImpl implements ChairIF {
private static final Lock lock = new ReentrantLock();
private static ChairIF instance = null;
public static ChairIF getInstance(String clazzName) {
//get class by clazzName
Class clazz = null;
try {
clazz = Class.forName(clazzName);
} catch (ClassNotFoundException ex) {
lock.lock();
try {
if (instance == null) {
instance = new ChairImpl();
}
} finally {
lock.unlock();
}
}
//init singleton instance of clazzName
if (instance == null) {
lock.lock();
try {
if (instance == null) {
instance = (ChairIF) clazz.newInstance();
} else {
if (instance.getClass() != clazz) {
instance = (ChairIF) clazz.newInstance();
}
}
} catch (Exception ex) {
instance = new ChairImpl();
} finally {
lock.unlock();
}
} else {
lock.lock();
try {
if (!instance.getClass().getName().equals(clazz.getName())) {
instance = (ChairIF) clazz.newInstance();
}
} catch (Exception ex) {
instance = new ChairImpl();
} finally {
lock.unlock();
}
}
return instance;
}
public int getLeg() {
return 4;
}
public void test() {
throw new UnsupportedOperationException();
}
}
class ThreeLegChair extends ChairImpl {
public ThreeLegChair() {}
public int getLeg() {
return 3;
}
public void test() {
int i = 0;
while(i < 10000) {
System.out.println("i: " + i++);
}
}
}
class NoLegChair extends ChairImpl {
public NoLegChair() {}
public int getLeg() {
return 0;
}
public void test() {
int j = 0;
while(j < 5000) {
System.out.println("j: " + j++);
}
}
}
public class Test {
public static void main(String[] args) {
System.out.println(ChairImpl.getInstance("ThreeLegChair").getLeg());
System.out.println(ChairImpl.getInstance("NoLegChair").getLeg());
/***
TODO: build logic to run 2 test() simultaneously.
ChairImpl.getInstance("ThreeLegChair").test();
ChairImpl.getInstance("NoLegChair").test();
****/
}
}
As you can see, I did put some test code in 2 subclasses. ThreeLegChair is to loop from 0 to 10000 and print it out. NoLegChair is to loop only from 0 to 5000 and print it out.
The result I got in the console log is correct. ThreeLegChair printed i from 0 to 10000. NoLegChair printed j from 0 to 5000.
Please share me your thought :)
Singleton pattern is achieved using the concept of private constructor i.e. the class itself is responsible for creating single instance of the class (singleton) and preventing other classes from creating objects.
Now as the constructor is private, you cannot inherit the singleton class at first place. In your case, I do not see a private constructor which makes it vulnerable to object creation from other classes accessing it.
Singleton pattern examples:
Using enumerations in Java
enum SingletonEnum {
SINGLE_INSTANCE;
public void doStuff() {
System.out.println("Singleton using Enum");
}
}
Lazy initialization approach
class SingletonClass {
private static SingletonClass singleInstance;
private SingletonClass() {
// deny access to other classes
}
// The object creation will be delayed until getInstance method is called.
public static SingletonClass getInstance() {
if (null == singleInstance) {
// Create only once
singleInstance = new SingletonClass();
}
return singleInstance;
}
}
However, the above example may not guarantee singleton behavior in multithreaded environment. It is recommended to use double checked locking mechanism to ensure that you have created a single instance of this class.
The code you post isn't an implementation of the singleton pattern.
Quite simply, you can do:
ChairImpl ci = new ChairImpl();
And instantiate as many as you want.
The traditional method of implementing the singleton pattern is the make the constructor private, have a private static field that holds the single instance of the class, and a static getInstance() method that either instantiates that instance or returns the existing one. Making that threadsafe involves either declaring it synchronized or using a locking scheme.
The private constructor bit makes it so you can't inherit from it.
That said, in Java the preferred way is using an enum which provides all the hard parts for free:
public enum MySingleton {
INSTANCE;
public int getLeg() {
return 4;
}
}
And using as:
MySingleton ms = MySingleton.INSTANCE;
int leg = ms.getLeg();
Singletons usually have private constructor. Your class is not following proper Singleton pattern. otherwise you would not be inherit your singleton class.
So I have a few 'Manager' classes, for example GroupManager. All these Managers are singletons.
Using this method for instancing:
private static GroupManager groupManager = null;
private GroupManager()
{
}
public static GroupManager Instance()
{
if (groupManager == null)
{
groupManager = new GroupManager();
}
return groupManager;
}
I'm thinking I should start to use some inheritance as they have a lot of copied methods.
The Instance() methods for each Manager is the same.
So for inheritance i can do this (obviously):
GroupManager extends Manager
Is it possible to use generics to use the same Instance method for all managers, something like:
public class Manager<E>
{
private static E instance = null;
public static E Instance()
{
if (instance == null)
{
instance = new E();
}
return instance;
}
}
I think that makes sense :)
So then you would do GroupManager.Instance() like normal.
You don't understand how generics and statics work. If you have a static field or method (such as "instance" or instance()), which can be called without instantiating the class Manager, how do you expect the JVM (and the compiler even) to know what type E is supposed to be?
Here's an example, as per G_H's suggestion:
GeneralManager and AreaManager both extend Manager
The Manager class is the only one that has the getInstance() static method:
public class Manager {
private static Map<Class<? extends Manager>,Manager> INSTANCES_MAP = new java.util.HashMap<Class<? extends Manager>, Manager>();
//Also, you will want to make this method synchronized if your application is multithreaded,
//otherwise you mihgt have a race condition in which multiple threads will trick it into
//creating multiple instances
public static <E extends Manager> E getInstance(Class<E> instanceClass) throws InstantiationException, IllegalAccessException {
if(INSTANCES_MAP.containsKey(instanceClass)) {
return (E) INSTANCES_MAP.get(instanceClass);
} else {
E instance = instanceClass.newInstance();
INSTANCES_MAP.put(instanceClass, instance);
return instance;
}
}
}
Nope, it's not gonna work. Java uses generics at compile time for type checking, but doesn't generate extra classes or retain info regarding type parameters at runtime.
When you declare Manager<E> with that type parameter E, that's something that will only play a role in an actual instance. You could have a subclass like GroupManager extends Manager<String> or whatever, but that's not magically gonna generate a variety of the static method.
Static methods and members belong with a class, not an instance. So trying to use generics there, which are intended for typing instances, isn't gonna fly.
If you make your group manager class as follows then you can call your instance method.
public class GroupManager extends Manager<GroupManager>{}
And in your Manager class try this...
public class Manager<E>
{
private static E instance = null;
public static E Instance()
{
try {
return instance.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
Or if you know the object you want an instance for, just make the method generic
public static <T> T getInstance(Class<T> t){
try {
return t.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
I havn't tried any of this so not sure if it will work.
Injecting the constructor in a generic context. Cash is not thread safe, but is only used in static context so its fine if you don't miss use it
public class Example {
public static class MySingletonClass {
}
public interface Provider<T> {
T get();
}
static final Provider<MySingletonClass> myClassInstanceProvider = new Cash<MySingletonClass>(new Provider<MySingletonClass>() {
#Override
public MySingletonClass get() {
return new MySingletonClass();
}
});
public static class Cash<T> implements Provider<T> {
private Provider<T> provider;
public Cash(Provider<T> provider) {
this.provider = provider;
}
#Override
public T get() {
final T t = provider.get();
provider = new Provider<T>() {
#Override
public T get() {
return t;
}
};
return t;
}
}
}
public class Manager<E>{
private static Object instance = null;
public static E Instance() {
if (instance == null)
{
instance = new E();
}
return (E)instance;
}
}