最近在用druid的数据库连接池,在eclipse代码运行正常,当打包成jar就会报
java.lang.NoClassDefFoundError: Could not initialize class***的错误,因为开发进度的原因只能抽时间查问题.后来发现是连接池类中static初始化的问题.原来参考的代码出处:点击打开链接.
其中涉及到静态块、静态变量、静态方法、构造函数的加载顺序,不清楚的可以自己写个简单的程序测试一下。
问题总结:
1.java.lang.NoClassDefFoundError: Could not initialize class错误提示不是找不到类,与NoClassFoundException错误不要混淆。
2.在IDE运行正常,但是打包后异常,可能与加载的properties等文件的编码格式错误读取不到有关。(应该不会有人忘记把相关文件放到目录下吧?)
3.应当熟悉单例模式内涵,关于单例模式大把的高人总结.
更改后代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.Properties;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.since.emp.service.OrderSyncs;
/**
* 要实现单例模式,保证全局只有一个数据库连接池
*/
public class DbPoolConnection {
String logTitle = "DBPoolConnection";
private static DbPoolConnection dbPoolConnection = null;
private static DruidDataSource druidDataSource = null;
static {
Init();
}
private DbPoolConnection() {
}
private static void Init()
{
try {
Properties properties = loadPropertiesFile("db.properties");
OrderSyncs.logger.info("【logTitle】"+"读取文件成功");
druidDataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties); // DruidDataSrouce工厂模式
} catch (Exception e) {
OrderSyncs.logger.info("【logTitle】"+"获取配置失败");
}
}
/**
* 数据库连接池单例
*
* @return
*/
public static synchronized DbPoolConnection getInstance() {
if (null == dbPoolConnection) {
dbPoolConnection = new DbPoolConnection();
}
return dbPoolConnection;
}
/**
* 返回druid数据库连接
*
* @return
* @throws SQLException
*/
public DruidPooledConnection getConnection() throws SQLException {
return druidDataSource.getConnection();
}
/**
* @param string
* 配置文件名
* @return Properties对象
*/
private static Properties loadPropertiesFile(String fullFile) {
if (null == fullFile || fullFile.equals("")) {
throw new IllegalArgumentException("Properties file path can not be null" + fullFile);
}
InputStream inputStream = null;
Properties p = null;
try {
inputStream = new FileInputStream(new File(fullFile));//原来是决定路径,现在用相对路径
p = new Properties();
p.load(inputStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != inputStream) {
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return p;
}
}