Hi Below is my code which will use as Connection Factory class. But i am getting java.lang.ExceptionInInitializerError. Please advice how to fix? I assume this is the trap because of static block, but not aware what exactly is this.
package j2ee.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
public class ConnFactory
{
public static Properties prop;
static
{
prop=new Properties();
try {
prop.load(ConnFactory.class.getClassLoader().getResourceAsStream("DBConfig.properties"));
} catch (Exception e) {
e.printStackTrace();
}
}
private static ConnFactory instance = new ConnFactory();
public static final String URL = prop.getProperty("DEVURL");
public static final String USER = prop.getProperty("DEVUSER");
public static final String PASSWORD = prop.getProperty("DEVPASSWORD");
public static final String DRIVER_CLASS = prop.getProperty("DEVDRIVER_CLASS");
private ConnFactory() {
try {
Class.forName(DRIVER_CLASS);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private Connection createConnection() {
Connection connection = null;
try {
connection = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (Exception e) {
System.out.println("ERROR: Unable to Connect to Database.");
}
return connection;
}
public static Connection getConnection() {
return instance.createConnection();
}
public static void main(String a[])
{
Connection test=ConnFactory.getConnection();
System.out.println("Done");
}
}
Error is :
Caused by: java.lang.NullPointerException
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:188)
at j2ee.dao.ConnFactory.<init>(ConnFactory.java:28)
at j2ee.dao.ConnFactory.<clinit>(ConnFactory.java:20)
private static ConnFactory instance = new ConnFactory(); // DRIVER_CLASS is null at this point
...
public static final String DRIVER_CLASS = ...;
You create an instance of ConnFactory before DRIVER_CLASS is initialized, therefore DRIVER_CLASS is null in the constructor of ConnFactory.
You need to reverse the order of these static field declarations:
public static final String DRIVER_CLASS = ...;
...
private static ConnFactory instance = new ConnFactory()
Actually, in my opinion it would be better to get rid of these static fields at all. Just make them non-static and initialize them in constructor.
You can also pass an instance of Properties into constuctor to decouple connection creation from storage of connection properties. If you do so, you will be able to use different sets of properties in different cases (for example, for test and production environments).
Related
I have a PowerMock
#Test
public void testDueSoonQueryOperation () {
try {
PowerMockito.whenNew(InitialContext.class).withNoArguments().
thenReturn((InitialContext) mockInitialContext);
} catch (Exception e) { e.printStackTrace(); }
try {
PowerMockito.when(lookup(anyString())).thenReturn(mockDataSource);
} catch (NamingException e) { e.printStackTrace(); }
try {
PowerMockito.when(mockDataSource.getConnection(anyString(), anyString())).thenReturn(mockDataConnection);
} catch (SQLException e) { e.printStackTrace(); }
QueryWorkItemHandler workItemHandler = new QueryWorkItemHandler();
BatchWorkItemHandler mockBatchHandler = PowerMockito.mock(BatchWorkItemHandler.class);
String dueIn7Days = "dueIn7Days";
HashMap<String, Object> taskDue7DaysMap = new HashMap<>();
taskDue7DaysMap.put(dueIn7Days,dueIn7Days);
PowerMockito.when(mockBatchHandler.handleMessageType(any(),
eq("SOON"), anyBoolean(), anyBoolean())).thenReturn(taskDue7DaysMap);
Map<String, Object> results = workItemHandler.doQueryOperation("SOON");
...
to test a class that uses JDBC to call a database. I mocked the Connection, DataSource, and InitialContext, but from the log messages the test seems to be using the real Connection, DataSource, and InitialContext. - why is it not using the mocked datasource, connection, and context? What do I need to add to have it use the mock's for these calls? If I replace a mock instance with (class of mock).class the compiler complains that the method does not exist for the class, e.g.,
PowerMockito.when((Context.class).lookup(Mockito.anyString()))
so I doubt it is simply a problem with my "when" clauses. The method being called in the class being test is
public class QueryWorkItemHandler extends AbstractLogOrThrowWorkItemHandler {
final static String dbJndiDataSource = System.getProperty("persistence.ds");
final static String dbUsername = System.getProperty("database.username");
final static String dbPassword = System.getProperty("database.password");
static BatchWorkItemHandler queryHelper = new BatchWorkItemHandler ();
public HashMap<String, Object> doQueryOperation(String messageType) {
try {
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup(dbJndiDataSource);
Connection conn = ds.getConnection(dbUsername, dbPassword);
(up through the line that throws a null pointer exception because dbUsername is a property not set up in the mock.) If the Mock were being used it seems like the call to getConnection would be covered by
PowerMockito.when(mockDataSource.getConnection(anyString(),anyString())).thenReturn(mockDataConnection);
I'm using redis with the help of jedis client. Attaching the code snippet for key value set/get here. Here I'm expecting my jedisPool to get initialised only once but it is getting initialised multiple times. Not sure where I'm going wrong. Scratching my head for several days with it. I have no clues why it does multiple initialisation.
//$Id$
package experiments.with.truth;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisClientUtil {
private static JedisPool pool; //I persume the deafult value initialised in my static variable would be null
static int maxActiveConnections = 8;
static int maxWaitInMillis = 2000;
static String host = "127.0.0.1";
static int port = 6379;
static int REDIS_DB = 1;
public static void initRedisClient() throws Exception {
try {
Class classObj = Class.forName("redis.clients.jedis.JedisPool");
if (classObj != null && pool == null) {
JedisPoolConfig jedisConfig = new JedisPoolConfig();
jedisConfig.setMaxTotal(maxActiveConnections);
jedisConfig.setMaxWaitMillis(maxWaitInMillis);
pool = new JedisPool(jedisConfig, host, port);
System.out.println("Pool initialised successfully !");
}
} catch(ClassNotFoundException ex) {
System.out.println("Couldn't initialize redis due to unavailability of jedis jar in your machine. Exception : " + ex);
}
}
public Jedis getJedisConnection() {
if(pool == null) {
initRedisClient();
}
return pool.getResource();
}
private static void returnJedis(Jedis jedis) {
try {
pool.returnResource(jedis);
} catch(Exception ex) {
ex.printStackTrace();
}
}
public static String getValue(String key) throws Exception{
Jedis jedisCon = null;
try {
jedisCon = getJedisConnection();
jedisCon.select(REDIS_DB);
String val = jedisCon.get(key);
return val;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedisCon != null) {
returnJedis(jedisCon);
}
}
return null;
}
public void addValueToRedis(String key, String value) {
Jedis jedisCon = null;
try {
jedisCon = getJedisConnection();
jedisCon.select(REDIS_DB);
jedisCon.set(key, value);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedisCon != null) {
returnJedis(jedisCon);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Value : " + getValue("a"));
System.out.println("Value : " + getValue("b"));
System.out.println("Value : " + getValue("c"));
}
}
I could see this debug log Pool initialised successfully multiple times when my program runs. Can someone help me find the loophole in this? Or how could I make this better (or make to behave it as expected) by initialising only once throughout the entire program.
Looks like a basic multithreading case. Your app asks for 5 connections in a short time. All of them see that pool==null and proceed initializing it.
Easy solution: public static synchronized void initRedisClient() throws Exception {
update and private static volatile JedisPool pool; otherwise you may get null pointer exception.
For more complex and performant solutions search 'efficient lazy singletor in java', which will most probably lead you to Enum solution.
I try to load properties file as below,
public class A_Main {
private static FileReader reader = new FileReader("D:\\Selenium_Workspace\\SeleniumTEST\\lists.properties");
private static Properties properties = new Properties();
private static properties.load(reader);
public static String UserName = properties.getProperty("lists.user");
public static String Passwd = properties.getProperty("lists.password");
......
......
......
public static void main(String[] args) throws IOException {
Configuration_Report conf = new Configuration_Report();
try {
conf.conf_report(UserName, Passwd);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
......
......
......
However, in eclipse it marked an error under below code,
private static properties.load(reader);
I try to change everything to public static also, however it seem the properties file cannot be load as reader seem not recognize.
As shared by Elliott above, you need to call the load function either from the static block. If you call it from the static block then you will have to take care that you initialize username and password (and any other dependencies) as well in the static block. Or the other option would be to initialize them at the starting of the main function:
Static Block:
public class A_Main {
private static Properties properties = new Properties();
public static String UserName = null;
public static String Passwd = null;
static{
try (FileReader reader = new FileReader("D:\\Selenium_Workspace\\SeleniumTEST\\lists.properties"))
{
properties.load(reader);
UserName = properties.getProperty("lists.user");
Passwd = properties.getProperty("lists.password");
} catch (IOException e) {
e.printStackTrace();
}
}
......
......
......
public static void main(String[] args) throws IOException {
Configuration_Report conf = new Configuration_Report();
try {
conf.conf_report(UserName, Passwd);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
......
......
......
Inside Main Function:
public class A_Main {
private static Properties properties = new Properties();
public static String UserName = null;
public static String Passwd = null;
......
......
......
public static void main(String[] args) throws IOException {
try (FileReader reader = new FileReader("D:\\Selenium_Workspace\\SeleniumTEST\\lists.properties"))
{
properties.load(reader);
UserName = properties.getProperty("lists.user");
Passwd = properties.getProperty("lists.password");
Configuration_Report conf = new Configuration_Report();
conf.conf_report(UserName, Passwd);
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
......
......
......
That is not valid syntax for invoking a function on a class member. You could use a static initialization block. And that FileReader constructor can also throw an Exception. You could move that initialization into the same block. Like,
private static FileReader reader;
private static Properties properties = new Properties();
static {
try {
reader = new FileReader("D:\\Selenium_Workspace\\SeleniumTEST\\lists.properties");
properties.load(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
I want to instantiate a URL as a private field in a class, but I can't catch the MalformedURLException. I've tried using a static initialization block, but that doesn't work either. How do I solve this?
public class MyClass{
private final static URL DEFAULT_URL = new URL("http://www.yadayada.com?wsdl")
...
}
You will need to throw something in the case of an exception. An Error should do the job.
public class MyClass{
private static final URL DEFAULT_URL;
static {
try {
DEFAULT_URL = new URL("http://www.yadayada.com?wsdl")
} catch (java.net.MalformedURLException exc) {
throw new Error(exc);
}
}
...
}
In case an exception is thrown (it shouldn't be) the class will fail to initialse.
A simple workaround is to create a static method:
private final static URL DEFAULT_URL = getDefaultUrl();
private static URL getDefaultUrl() {
try {
return new URL("http://www.yadayada.com?wsdl");
} catch (Exception e) {
//what do you want to do here?
return null; //that is an option
throw new AssertionError("Invalid URL"); //that is another one
}
}
You can do it in the static block
public class MyClass {
private final static URL DEFAULT_URL;
static {
try {
DEFAULT_URL = new URL("http://www.yadayada.com?wsdl");
} catch (MalformedURLException e) {
}
}
Using static block initializer - you may catch exception inside the block.
However, I would not recommend to store it as final class field as URI. Place it as String constant and initialize in constructor or special init() intance method
Try below. you cannot use final keyword for below:
private static URL DEFAULT_URL = null;
static{
try {
DEFAULT_URL = new URL("http://www.yadayada.com?wsdl");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The class partially shown below contains a main method. When I run the code, I see a NullPointerException (NPE) and then an error message - "Could not find the main class, program will exit". My understanding is that if I get NPE, it means that the code is running, ie the JRE found a main method to begin execution, so why do I get the error message?
This is the console output
java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at com.MyWorldDemo.getValue(MyWorldDemo.java:57)
at com.MyWorldDemo.<clinit>(MyWorldDemo.java:23)
Exception in thread "main"
In a nutshell:
username is stored in a properties file.
properties file is like this username=superman....etc
here is some code example
class MyClass {
private final static String username = getData("username"); // ERROR HERE
private static Properties prop;
// more variables
static {
prop = new Properties();
try {
FileInputStream fis = new FileInputStream("MyDB.properties");
prop.load(fis);
} catch (IOException ex) {
ex.printStackTrace();
}
}
// this method will assign a value to my final variable username.
public static String getData(String props) {
String property = prop.getProperty(props);// ERROR HERE !!!
return property;
}
}
Initializing of static variables depends on its position in code (variables are initialized from top to bottom). In your code
private final static String username = getData("username"); // ERROR HERE
private static Properties prop;
// more variables
static {
prop = new Properties();
try {
FileInputStream fis = new FileInputStream("MyDB.properties");
prop.load(fis);
} catch (IOException ex) {
ex.printStackTrace();
}
}
prop object will be initialized after username in static block, but since to initialize username prop is necessary and its not initialized yet you get NPE. Maybe change your code to something like:
private static Properties prop = new Properties();
private final static String username = getData("username");
static {
try {
FileInputStream fis = new FileInputStream("MyDB.properties");
prop.load(fis);
} catch (IOException ex) {
ex.printStackTrace();
}
}
You have a static initialization at line 23 of MyWorldDemo that is calling the method getValue, which is then causing a NPE at line 57, therefore the class cannot be instantiated, therefore the main method cannot be called. It probably looks something like:
class MyWorldDemo {
private static String foo = getValue("username");
private static Properties prop;
// This happens too late, as getValue is called first
static {
prop = new Properties();
try {
FileInputStream fis = new FileInputStream("MyDB.properties");
prop.load(fis);
} catch(IOException ex) {
ex.printStackTrace();
}
}
// This will happen before static initialization of prop
private static String getValue(String propertyValue) {
// prop is null
return prop.getProperty(propertyValue);
}
public static void main(String args[]) {
System.out.println("Hello!"); // Never gets here
}
}