I would like to use db4o and I`m learning this using in youtube.com tutorial. Unfortunately I'm not able to find mistake in my code. I would like to know why I have got there error? I added all important library.
Code important class:
package data;
import com.db4o.*;
import com.db4o.config.EmbeddedConfiguration;
public class DataConnection {
private static DataConnection INSTANCE =null;
private final String PATH = "test.db4o";
private static ObjectContainer db;
private DataConnection(){}
private synchronized static void createInstance(){
if (INSTANCE ==null){
INSTANCE = new DataConnection();
INSTANCE.performConnection();
}}
public void performConnection() {
EmbeddedConfiguration config = Db4oEmbedded.newConfiguration();
db = Db4oEmbedded.openFile(config, PATH);
}
public static ObjectContainer getInstance() {
if(INSTANCE == null) createInstance();
return db;
}
public static void closeConnection() {
try{
db.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Here is this tutorial (important thing 5:44):
http://www.youtube.com/watch?v=dcNfkED53to
Try replacing
new DataConnection.getInstance()
with
DataConnection.getInstance()
The keyword new is only used when creating a new object. Here you are calling a static method.
Related
In one of the interview I got asked about to how to make sure single object is present of a Singleton class when used with multiple classloaders.I followed this SO Question but I couldn't understand how we should invoke the getClass(). As there is no information about it in the answer and as well as in the link provided in the answer. I am new to classloaders and things aren't that clear for me. I have tried the code and tried multiple combination but every time I am getting two instance instead of one.
package com.design_pattern;
import java.io.*;
import java.lang.reflect.Constructor;
public class SIngletonPattern {
public static void main(String[] args) throws Exception {
DatabaseConnection databaseConnection = DatabaseConnection.getDatabaseConnection();
ClassLoader classLoader = SIngletonPattern.class.getClassLoader();
System.out.println(classLoader);
//Class classs = classLoader.getClass().forName(DatabaseConnection.class.getName());
Class classs = DatabaseConnection.getClass(DatabaseConnection.class.getName());
System.out.println(classs.getName());
Constructor[] declaredConstructors = classs.getDeclaredConstructors();
DatabaseConnection db2 = null;
for (Constructor d:declaredConstructors) {
d.setAccessible(true);
db2 = (DatabaseConnection) d.newInstance();
}
if(db2 == null){
System.out.println("null");
}else{
System.out.println(databaseConnection == db2);
}
}
}
class DatabaseConnection implements Serializable {
private static volatile DatabaseConnection databaseConnection;
private DatabaseConnection() {
System.out.println("Instance created");
}
public static DatabaseConnection getDatabaseConnection() {
System.out.println("getInstance()");
if (databaseConnection == null) {
synchronized (DatabaseConnection.class) {
if (databaseConnection == null) {
databaseConnection = new DatabaseConnection();
}
}
}
return databaseConnection;
}
protected Object readResolve() {
return databaseConnection;
}
public static Class getClass(String classname)
throws ClassNotFoundException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader == null)
classLoader = DatabaseConnection.class.getClassLoader();
return (classLoader.loadClass(classname));
}
}
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.)
Can anyone tell me what does this thing do? Also if anyone can give an example if would be helpful.
public class ConnectionManager{
private static ConnectionManager instance = null;
.....}
Here is the complete code:
package com.gollahalli.main;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionManager
{
private static ConnectionManager instance = null;
private final String USERNAME = "root";
private final String PASSWORD = "root";
private final String H_CONN_STRING = "jdbc:hsqldb:data/explorecalifornia";
private final String M_CONN_STRING = "jdbc:mysql://localhost/explorecalifornia";
private DBType dbType = DBType.MYSQL;
private Connection conn = null;
private ConnectionManager() { }
public static ConnectionManager getInstance() {
if (instance == null) {
instance = new ConnectionManager();
}
return instance;
}
public void setDBType(DBType dbType) {
this.dbType = dbType;
}
private boolean openConnection() {
try {
switch (dbType) {
case MYSQL:
conn = DriverManager.getConnection(M_CONN_STRING, USERNAME, PASSWORD);
return true;
case HSQLDB:
conn = DriverManager.getConnection(H_CONN_STRING, USERNAME, PASSWORD);
return true;
default:
return false;
}
}
catch (SQLException e) {
System.err.println(e);
return false;
}
}
public Connection getConnection() {
if (conn == null) {
if (openConnection()) {
System.out.println("Connection opened");
return conn;
} else {
return null;
}
}
return conn;
}
public void close() {
System.out.println("Closing connection");
try {
conn.close();
conn = null;
} catch (Exception e) { }
}
}
There is the singleton design pattern.
It used to make sure that only one instance of a class can be created.
public class MySingletonClass {
private static MySingletonClass instance;
public synchronized static MySingletonClass getInstance() {
if (instance == null) {
instance = new MySingletonClass(); // "lazy" initialization
}
return instance;
}
/**
* private constructor can be called only inside of MySingleton class, but not from outside.
*/
private MySingletonClass() {
// your code here
}
}
So, to get an instance of this class in the code, a developer does not use the constructor.
Developer uses the static method getInstance().
MySingletonClass mySingleton = MySingletonClass.getInstance();
Please be careful with singletons. Many novice developers abuse use of singletons and use them as global variables. Don't do it :)
UPDATE:
I added synchronized to the getInstance() method to make it thread safe.
It simply declares a field called instance whose type is ConnectionManager and initializes it to null (which is redundant because that would be its default value anyway).
Most likely the class is a singleton class (only one instance is allowed from them) judging by the instance field declaration and by the name of the class.
It's called the Singleton pattern.
This is used when you need only one object of a class, the singleton. It will be construct only one time and then you can access it through getInstance().
Naive implementation
public class SingletonDemo {
//Holds the singleton
private static SingletonDemo instance = null;
//Overrides default constructor, not to instantiate another one.
//Only getInstance will construct
private SingletonDemo() { }
//Only this method can construct a singleton, always call this one
public static SingletonDemo getInstance() {
if (instance == null) { //No singleton yet, create one
instance = new SingletonDemo();
}
//return the singleton (created this time or not)
return instance;
}
}
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 want to make a singleton class Phone, so that it can be initializable (with number) and also concurrent-safe. So, here is what I came with:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class PhoneTest {
public static void main(String... args){
System.out.println(Phone.getInstance().getNumber());
}
static final class Phone {
private final String number;
private final static Phone instance;
static {
instance = new Phone(PhonePropertyReader.readPhoneNumber());
}
private Phone(String number) {
this.number = number;
}
public static Phone getInstance() {
if (instance == null) throw
new IllegalStateException("instance was not initialized");
return instance;
}
public String getNumber() {
return number;
}
}
static final class PhonePropertyReader {
static String readPhoneNumber() {
File file = new File("phone.properties");
String phone = "";
System.out.println(file.getAbsolutePath());
if (!file.exists()) {
return phone = "555-0-101";
}
try {
BufferedReader r = new BufferedReader(new FileReader(file));
phone = r.readLine().split("=")[1].trim();
r.close();
} catch (IOException e) {
}
return phone;
}
}
}
also I have a file phone.properties containing
phone=12345
Is it a good solution? Is it concurrent safe?
I believe that Enum still the best way to implement thread-safe singletons in java.
I would discourage you to use singletons (Check this other question)
Otherwise, your code is thread-safe since the only affectation you do is in a static {} area which is, by definition, thread safe.
Btw, why not incorporate your readPhoneNumber() method directly in your phone class ?