derby In memory database + junit - junit

I got an exception below when trying to use derby in memory database in JUNITTEST.
java.sql.SQLNonTransientConnectionException: Database 'memory:testDB'
dropped. at
org.apache.derby.iapi.error.StandardException.newException(Unknown
Source)
#Before
public void setUp() throws Exception {
String driver = "org.apache.derby.jdbc.EmbeddedDriver";
String connectionURL = "jdbc:derby:memory:testDB;create=true";
Class.forName(driver);
Connection conn = DriverManager.getConnection(connectionURL);
super.setUp();
}
#After
public void tearDown() throws Exception {
String connectionURL = "jdbc:derby:memory:testDB;drop=true";
DriverManager.getConnection(connectionURL);
}

If you are using Maven for your build, you can use the derby-maven-plugin, which I wrote and is available on GitHub and via Maven Central. It will take care of starting and stopping the database for you before your tests.
You can check here for my answer to a similar question.

Related

IntelliJ cannot find MySQL JDBC driver

I have added MySQL JDBC driver but I keep getting the following error: No suitable driver found for jdbc.
Here's the code that I'm trying:
public class Test extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp1", "root", "");
System.out.println("Connected successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here are the project settings.
As soon as I add MySQL jar, one following problem appears:
I have tried all of the three options above, but I keep getting the same error.

Cordapp- Hikari Connection Pool class not found for MySql ConnectionPoolDataSource

I am building an workflow for Corda. I want to use the Hikari connection pool library for connecting to MySql database. I AM NOT trying to replace the, ledger H2 database. This database is for storing/retrieving some information, which is not needed in the ledger. I am able to connect to MySql WITHOUT Hikari. However when I use Hikari, I get an error.
java.lang.ClassNotFoundException: com.mysql.cj.jdbc.MysqlConnectionPoolDataSource
I have tested the Hikari code, as a standalone jar file. It works fine. It is a combination of the way corda loads and runs the jar files, inside cordapps directory, which is causing the issue. Since the class is part of the jar. This seems it a little off
I have added the MySql dependency, inline with what is mentioned in https://docs.corda.net/cordapp-build-systems.html#setting-your-dependencies
I am also able to connect to the MySql DB, if I am not using Hikari.
I explored the cordapp jar .
And I could see that the requisite jar is present inside the cordapp jar.
Gradle dependencies for the cordapp
dependencies {
testCompile "junit:junit:$junit_version"
// Corda dependencies.
cordaCompile "$corda_release_group:corda-core:$corda_release_version"
cordaRuntime "$corda_release_group:corda:$corda_release_version"
testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
runtime "mysql:mysql-connector-java:8.0.11"
cordaCompile "com.zaxxer:HikariCP:2.5.1"
// CorDapp dependencies.
cordapp project(":contracts")
}
Sample code
public class DataSource {
private static final Logger logger = LoggerFactory.getLogger(DataSource.class);
private static HikariConfig config = new HikariConfig();
private static HikariDataSource ds;
static {
try {
logger.info("Connecting with connection pool datasource");
config.setDataSourceClassName("com.mysql.cj.jdbc.MysqlConnectionPoolDataSource");
config.addDataSourceProperty("useSSL", "false");
config.addDataSourceProperty("user", "username");
config.addDataSourceProperty("password", "password");
config.addDataSourceProperty("serverName", "localhost");
config.addDataSourceProperty("useSSL", "false");
config.addDataSourceProperty("port",Integer.parseInt("3306"));
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
config.addDataSourceProperty("requireSSL", "false");
config.addDataSourceProperty("serverTimezone", "UTC");
config.addDataSourceProperty("useServerPrepStmts", "true");
config.addDataSourceProperty("allowPublicKeyRetrieval", "true");
config.addDataSourceProperty("databaseName", "database");
config.setPoolName("Hikari-MySql Pool Name");
logger.error("-- Create Hikari Datasource with config {} --", config);
ds = new HikariDataSource(config);
} catch (Throwable t) {
logger.error("Error Occurred during Datasource Initializaiton", t);
throw t;
}
}
private DataSource() {
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
public class MySqlConnection {
static private final Logger logger = LoggerFactory.getLogger(MySqlConnection.class);
public Connection getMySqlConnection() {
Connection conn = null;
try {
conn = DataSource.getConnection();
logger.info("------------> Got conne :: " + conn);
} catch (SQLException e) {
logger.error("SQLException :: " + e);
}
return conn;
}
}
public class DataSourceTest {
static private final Logger logger = LoggerFactory.getLogger(DataSourceTest.class);
public static void main(String[] args) {
MySqlConnection mySqlConnection = new MySqlConnection();
Connection conn = null;
try {
conn = mySqlConnection.getMySqlConnection();
logger.info("------------> Got connection :: " + conn);
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery("{some select statement}");
} catch (SQLException e) {
logger.error("SQLException :: " + e);
}
}
}
Exception:
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.mysql.cj.jdbc.MysqlConnectionPoolDataSource
at com.zaxxer.hikari.util.UtilityElf.createInstance(UtilityElf.java:90) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.pool.PoolBase.initializeDataSource(PoolBase.java:314) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.pool.PoolBase.<init>(PoolBase.java:108) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:99) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:71) ~[HikariCP-2.5.1.jar:?]
If I run the code from a main class inside a jar, it works. But it does not work from inside a cordapp
In MySQL for HikariCP use setJdbcUrl instead of setDataSourceClassName
config.setJdbcUrl("jdbc:mysql://localhost:3306/simpsons");
The MySQL DataSource is known to be broken with respect to network timeout support. Use jdbcUrl configuration instead.
Check your dependency tree. I think you have some collision with "mysql-connector-java" dependency, which cause mess in class loader.

How to create a database during spring context initialization

I need to create a database named test in my local mysql server which i will use to setup my datasource bean. I am using the following spring configuration for setting up the datasource and jdbctemplate for my testing
#Configuration
class Config {
#Bean(initMethod = "setupDatabase")
public DataSource getDataSource() {
String url = "jdbc:mysql://localhost:3306/test";
DriverManagerDataSource dataSource = new DriverManagerDataSource(
url, settings.getUsername(), settings.getPassword());
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
return dataSource;
}
#Bean
public JdbcTemplate getJdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(((DataSourceTransactionManager)transactionManager()).getDataSource());
return jdbcTemplate;
}
#Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(getDataSource());
}
#Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}
private DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(schemaScript);
return populator;
}
#PostConstruct
public void setupDatabase() {
String url = "jdbc:mysql://localhost:3306";
try {
Connection connection = DriverManager.getConnection(url, settings.getUsername(), settings.getPassword());
Statement statement = connection.createStatement();
statement.execute("create database test");
} catch (SQLException exception) {
LOGGER.error("Could not setup database for test", exception);
throw new RuntimeException(exception);
}
}
}
I am getting the following error Caused by:
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'test'
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:46)
Can someone explain what is going wrong with this configuration?
Did you create the test database at your local mysql? You need to create the db first to connect from your application. If you want to create a database by executing sql query connect to the database as root user and create the db.
The source of the exception: your setupDatabase() method is executed actually by Spring AFTER getDataSource() cause #Bean(initMethod = "setupDatabase") forces Spring to execute initMetod AFTER a bean creation for the bean initialization. But it's not you expect here.
You need somehow define your getDataSource() is depended on setupDatabase(). E.g. with a help of #DependsOn annotation.
Also see Spring 3 bean instantiation sequence
P.S. but why you don't simple manually add setupDatabase() call into getDataSource() method?

jsp mysql server connection timeout

hi i am doing an jsp project. and i deploy my project on apache tomcat. i use mysql as databese.
when i deploy project on remote server it is run good. but after some hours it gives me sql error. then i go back my apache server and start projecet again it run and after some hours it gives me same sql error again. i dont know the problem. is that caused from my java connection code or it is about mysql server. can some one tell me why it gives me sql error.?
public class ConnectionManager {
private String className = "com.mysql.jdbc.Driver";
private String userName ="username";
private String password = "password";
private String url = "jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf-8";
/**
* #uml.property name="connectionInstance"
* #uml.associationEnd
*/
private static ConnectionManager connectionInstance = null;
public ConnectionManager(){
}
public static synchronized ConnectionManager getInstance() {
if(connectionInstance == null) {
connectionInstance = new ConnectionManager();
}
return connectionInstance;
}
public Connection getConnection(){
Connection conn = null;
try {
Class.forName(className);
conn = DriverManager.getConnection (url, userName, password);
System.out.println("Connection Established");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
MySQL has a default connection timeout of 8 hours. So this means that you've kept a SQL connection open for too long. Your code suggests that you're creating only one connection on application's startup and reusing it application wide. This is very bad. This is not threadsafe.
You need to change your code so that you're not declaring and storing the SQL Connection as a static or instance variable anywhere in your code. Instead, it should be declared, created and closed within the shortest possible scope. Preferably within the very same method block as where you're executing the SQL query.
Here's a minor rewrite of your ConnectionManager which does the job properly:
public class ConnectionManager {
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String USERNAME ="username";
private static final String PASSWORD = "password";
private static final String URL = "jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf-8";
static {
try {
Class.forName(DRIVER);
}
catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(DRIVER + " missing in classpath!", e);
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USERNAME, PASSWORD);
}
}
Use it as follows:
public class SomeDAO {
public SomeEntity find(Long id) throws SQLException {
Connection connection = null;
// ...
try {
connection = ConnectionManager.getConnection();
// ...
}
finally {
// ...
if (connection != null) try { connection.close(); } catch(SQLException ignore) {}
}
return someEntity;
}
To improve connecting performance, use a connection pool instead of DriverManager.
See also:
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
Are you closing connections properly after using them.

Failed to instantiate SLF4J LoggerFactory

So,
I'm working from this example BONECP:
package javasampleapps;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.jolbox.bonecp.BoneCP;
import com.jolbox.bonecp.BoneCPConfig;
/** A test project demonstrating the use of BoneCP in a JDBC environment.
* #author wwadge
*/
public class BoneCPExample {
/** Start test
* #param args none expected.
*/
public static void main(String[] args) {
BoneCP connectionPool = null;
Connection connection = null;
try {
// load the database driver (make sure this is in your classpath!)
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception e) {
e.printStackTrace();
return;
}
try {
// setup the connection pool
BoneCPConfig config = new BoneCPConfig();
config.setJdbcUrl("jdbc:mysql://domain/db");
config.setUsername("root");
config.setPassword("pass");
config.setMinConnectionsPerPartition(5);
config.setMaxConnectionsPerPartition(10);
config.setPartitionCount(1);
connectionPool = new BoneCP(config); // setup the connection pool
connection = connectionPool.getConnection(); // fetch a connection
if (connection != null){
System.out.println("Connection successful!");
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id from batches limit 1"); // do something with the connection.
while(rs.next()){
System.out.println(rs.getString(1)); // should print out "1"'
}
}
connectionPool.shutdown(); // shutdown connection pool.
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
I added slf4j in my Libraries menu in netbeans, adding
D:/Documents%20and%20Settings/DavidH/My%20Documents/NetBeansProjects/jars/slf4j-api-1.6.4.jar
and
D:/Documents%20and%20Settings/DavidH/My%20Documents/NetBeansProjects/jars/slf4j-log4j12-1.6.4.jar
to the library.
Then I made a Google Guava library and added the jar that they distribute for that to another library.
I then added both of the libraries to the project and hit run.
I now get this error:
Failed to instantiate SLF4J LoggerFactory
Reported exception:
java.lang.NoClassDefFoundError: org/apache/log4j/Level
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:128)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:108)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:279)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:252)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:265)
at com.jolbox.bonecp.BoneCPConfig.<clinit>(BoneCPConfig.java:60)
at javasampleapps.BoneCPExample.main(BoneCPExample.java:28)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Level
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 7 more
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Level
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:128)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:108)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:279)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:252)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:265)
at com.jolbox.bonecp.BoneCPConfig.<clinit>(BoneCPConfig.java:60)
at javasampleapps.BoneCPExample.main(BoneCPExample.java:28)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Level
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 7 more
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
What can I do to fix this?
If you include slf4j-log4j12-1.6.4.jar, then you must also include the log4j jar. Slf4j is a logging facade, which means it gives you a uniform interface to multiple other logging APIs.
The slf4j-log4j12 provides a conversion to the log4j API. As you don't include the log4j library, it throws an error. Not including the slf4j-log4j12 library should be enough (if only the slf4j-api library is included, then it should then default to a no-operation logger AFAIK).