Class Not Found Exception org//h2//Driver - java

I am learning Spring Framework and trying to inject properties from the .properties file.
This is my .properties file
sprint.datasource.username=hamnghi
sprint.datasource.password=hamnghi
sprint.datasource.url=jdbc:h2:~/test;
sprint.datasource.driver=org.h2.Driver;
When I tried to pass the driver field into the Class.forName(drive), the program could not connect to the
database and threw a java.lang.ClassNotFoundException: org/h2/Driver; but it printed the driver variable as "org.h2.Driver" to the console just fine.
My console screenshot
I also ran the program with Class.forName("org.h2.Driver"), and it ran fine; however, when I replaced it with the driver, it didn't work
This is my class.
package H2Database.db_connection;
import H2Database.functionality.Logging;
import org.springframework.beans.factory.annotation.Value;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Logger;
public class H2Connection {
private final static Logger logger = Logging.getLogger();
#Value("${sprint.datasource.url}")
private String url;
#Value("${sprint.datasource.username}")
private String username;
#Value("${sprint.datasource.password}")
private String password;
#Value("${sprint.datasource.driver}")
private String driver;
public Connection open(){
try {
Class.forName(driver);
Connection connection = DriverManager.getConnection(url, username, password);
return connection;
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
#Override
public String toString() {
return "H2Connection{" +
"url='" + url + '\'' +
", username='" + username + '\'' +
", driver='" + driver + '\'' +
'}';
}
}

EDITED
You have trailing ; in your config. remove it
The exception means the specific class is not found in the classpath.
You need to add the dependency contains the corresponding implemenation for h2:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

You should complete the following steps to Configure the H2 database to your Spring MVC application.
Step 1: Add the following dependency in the pom.xml file
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
Step 2: configure these properties in the application.properties file.
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
Note: Spring MVC does not auto configure the properties of the
application.properties. You should configure it using configuration
class.
Step 3: Configure the Database.
#Configuration
#PropertySource("classpath:application.properties")
public class DataSourceConfig {
#Value("${sprint.datasource.url}")
private String url;
#Value("${sprint.datasource.username}")
private String username;
#Value("${sprint.datasource.password}")
private String password;
#Value("${sprint.datasource.driver}")
private String driver;
#Bean
public DataSource testDataSource() {
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName(driver);
bds.setUrl(url);
bds.setUsername(username);
bds.setPassword(password);
return bds;
}
}

Related

Firebird connection using Spring Boot

How to create a Firebird connection using Spring Boot to make views in SQL using the Firebird database? I have no idea how to build this.
try {
Class.forName("org.firebirdsql.jdbc.FBDriver");
Connection con= DriverManager.getConnection("jdbc:firebirdsql:localhost/3050:C:/DB/DASHBOARD.FDB","sysdba","masterkey");
Statement stm= con.createStatement();
ResultSet res= stm.executeQuery("SELECT * FROM TBLEMPLOYEE");
while (res.next()) {
System.out.println("DASHBOARD LASTNAME:"
+ res.getString("LASTNAME"));
}
} catch (Exception e) {
System.out.println(e);
}
I tried to make a connection string, but without success because Spring doesn't recognize it.
Take the following steps:
Go to https://start.spring.io/
Configure it with Maven (or Gradle if you prefer that)
Enter the desired coordinates for your project
Add dependency JDBC
Click Generate and unpack the zip to a location on your computer
Open the project in you favorite IDE
In the pom.xml, in the dependencies section add Jaybird (the Firebird JDBC driver):
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>jaybird</artifactId>
</dependency>
Or, if you used Gradle, add to the dependencies section of build.gradle:
runtimeOnly 'org.firebirdsql.jdbc:jaybird'
In src/main/resources/application.properties add:
spring.datasource.url=jdbc:firebirdsql://localhost/employee
spring.datasource.username=sysdba
spring.datasource.password=masterkey
In the package generated by the initializr (default com.example.demo), add a new class SimpleRunner:
package com.example.demo;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
#Component
public class SimpleRunner implements CommandLineRunner {
private final DataSource dataSource;
public SimpleRunner(DataSource dataSource) {
this.dataSource = dataSource;
}
#Override
public void run(String... args) throws Exception {
try (var connection = dataSource.getConnection();
var stmt = connection.createStatement();
var rs = stmt.executeQuery("select first_name, last_name from employee")) {
while (rs.next()) {
System.out.printf("%s %s%n",
rs.getString("first_name"), rs.getString("last_name"));
}
}
}
}
This very basic application will connect to the Firebird example database employee, and print out the first and last names of the employees in the employee table.

JPA datasorce ignores username in properties file

I have a test class which I use to check if the connection to the database is established. The credentials are saved in a properties file. When I run the tests in eclipse everything works fine. But when I run a maven build the tests fail because the username used to connect to the database is not the one I set in the properties file. It is the windows username. This is my code:
Properties File:
driverClassName=oracle.jdbc.driver.OracleDriver
user=database_dev1
password=password_dev1
url=jdbc:oracle:thin:#MyAwsomeDatabase:1521:DEV01
Config Class:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories("de.xxx.bvd.mobisl.service")
#PropertySource("classpath:database.properties")
#ComponentScan("de.xxx.bvd.mobisl.service")
public class JPAConfig {
#Value("${driverClassName}")
protected String driverClassName;
#Value("${url}")
protected String url;
#Value("${user}")
protected String username;
#Value("${password}")
protected String password;
private static final Logger logger = Logger.getLogger(JPAConfig.class);
#SuppressWarnings("unchecked")
#Lazy
#Bean
public DataSource dataSource() {
try {
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
Class<? extends Driver> driver = (Class<? extends Driver>) Class.forName(driverClassName);
dataSource.setDriverClass(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
logger.info("created DataSource with username " + username + " and password " + password);
return dataSource;
} catch (ClassNotFoundException e) {
logger.error("cannot create datasource!!", e);
return null;
}
}
As I said, running from eclipse works fine. The logfile says:
[[XXX-LOG]] 2018-09-04 08:27:23 INFO JPAConfig:57 - created DataSource with username database_dev1
[[XXX-LOG]] 2018-09-04 08:27:27 INFO JPAConfigTest:52 - got result from database
But running from maven the logfile says:
[[XXX-LOG]] 2018-09-04 08:27:53 INFO JPAConfig:57 - created DataSource with username <<Windows-Username>>
How can I tell maven to use the username from the properties file?
${user} is replaced by maven with the environment variable user.
You can get this if you run mvn help:system
Solution rename the property to be more specific like
db.username
A side effect user is very ambiguous in bigger projects. If you rename it it is more cleary where it is used

Reading From Dynamically Updated Application.properties

I have application properties file which I am dynamically updating using maven build step.
mvn clean -Dusername=user1 -Durl=xxxx -Dpassword=xxxx -DskipTests
install
jdbc.url=${url}
jdbc.username=${username}
jdbc.password=${password}
I am reading these properties in the configuration class
#Configuration
#ImportResource("classpath:/spring-beans.xml")
#PropertySource("classpath:/application.properties")
public class ApplicationConfiguration {
#Value("${jdbc.url}")
private String url;
#Value("${jdbc.username}")
private String username;
#Value("${jdbc.password}")
private String password;
#Bean(name = "c3p0DataSource")
public ComboPooledDataSource dataSource() throws PropertyVetoException,
IOException {
logger.info("Creating Datasource for {}",System.getenv("SPRING_DATASOURCE_URL"));
// logger.info("Creating Datasource for username {}",
prop.getProperty("username"));
logger.info("Creating Datasource for {}", System.getenv("username"));
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
logger.info("User Name :" + username);//returning $username instead of user1
logger.info("password :" + password);
System.out.println("User name : " + username);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource; } }
I am not getting updated values instead I am getting $username, $password as values, can anyone help me what i am missing here ?
my modified properties file look like below
jdbc.url=xxxx
jdbc.username=user1
jdbc.password=xxxx
you should run
mvn clean -Djdbc.username=user1 -Djdbc.url=xxxx -Djdbc.password=xxxx -DskipTests install
Rather than using Spring's application property , I will suggest you to use another property file, store it on file system and use org.apache.commons.configuration.PropertiesConfiguration class to load values from this file.
org.apache.commons.configuration.PropertiesConfiguration has capability to reload property file on change.
https://commons.apache.org/proper/commons-configuration/userguide/howto_properties.html
If you are using maven add below dependency.
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.10</version>
</dependency>
When you say 'dynamically updated' it seems to me you just mean updated at build time and not at runtime. If so then you need to use the maven resources plugin, define the maven variables and use a different syntax in the properties file. This is covered in the properties and configuration section of the spring boot documentation
I have tried initialising data manually, which works. You can also give it a try.
You can try out the code below:
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Configuration;
#Configuration
#PropertySource("classpath:application.properties")
public class ApplicationConfiguration {
private Properties properties = new Properties();
public static String driverClass;
public static String dataSourceUrl;
public static String dataSourceUser;
public static String dataSourcePassword;
public ApplicationConfiguration() throws IOException {
properties.load(new InputStreamReader(ApplicationConfiguration.class.getResourceAsStream("/application.properties")));
driverClass = properties.getProperty("spring.datasource.driver-class-name");
dataSourceUrl = properties.getProperty("spring.datasource.url");
dataSourceUser = properties.getProperty("spring.datasource.username");
dataSourcePassword = properties.getProperty("spring.datasource.password");
}
// Other Code Details
}
Now I can easily use it like: ApplicationConfiguration.driverClass or ApplicationConfiguration.dataSourceUser.
Few other resources are also used by me from application.properties which I am not initialising manually and also not required while building jar. So only I am using #PropertySource("classpath:application.properties") to use other resources without initialising manually.
Try it once, It may help you :)

Implementing DataSource in Java to connect to my database

I'm trying to write a class that implements DataSource. This seems simple enough, but the examples I'm seeing for Oracle all declare the class like this:
public class ConnectionPoolingBean implements SessionBean {
....
}
I would expect to see something more like this:
public class MyDataSource implements DataSource {
....
}
Also, I don't understand how the connection is actually working. The getConnection() method only takes the arguments for username and password. So how am I connecting to my database?
Ultimately, what I need to understand is how do I connect to my database and return a result set from a query using DataSource. I just don't see any clear examples of how write a class to use this on my WebApp.
Here's what I've been reading from, which is now just confusing me.
https://docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html
http://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html
Use any connection pool for your use case.If you are using app server you can use app server connection pool or use opensource dbcp connection pool mechanism.
<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
Example
import org.apache.commons.dbcp2.BasicDataSource;
public class DataBaseUtility
{
private static BasicDataSource dataSource;
private static BasicDataSource getDataSource()
{
if (dataSource == null)
{
BasicDataSource ds = new BasicDataSource();
ds.setUrl("jdbc:mysql://localhost/test");
ds.setUsername("root");
ds.setPassword("password");
ds.setMinIdle(5);
ds.setMaxIdle(10);
ds.setMaxOpenPreparedStatements(100);
dataSource = ds;
}
return dataSource;
}
public static void main(String[] args) throws SQLException
{
try (BasicDataSource dataSource = DataBaseUtility.getDataSource();
Connection connection = dataSource.getConnection();
PreparedStatement pstmt = connection.prepareStatement("SELECT * FROM account");)
{
System.out.println("The Connection Object is of Class: "+connection.getClass());
try (ResultSet resultSet = pstmt.executeQuery();)
{
while (resultSet.next())
{
System.out.println(resultSet.getString(1) + "," + resultSet.getString(2) + "," + resultSet.getString(3));
}
}
catch (Exception e)
{
connection.rollback();
e.printStackTrace();
}
}
}
}

I can't connect to a database - program doesn't know where JAR file is

I am trying to copy an example from chapter 23 of Cay S. Horstmann's Big Java, which you can find online as a PDF file just in case if you need it as a reference: http://bcs.wiley.com/he-bcs/Books?action=chapter&bcsId=7872&itemId=1118431111&chapterId=87075
My program is supposed to connect to an Apache Derby database using the java utility tool in a shell window, but it doesn't work. What am I supposed to be entering into the shell window to fix this problem?
My folder structure looks like this in IntelliJ:
This is the code:
package Chapter23RelationalDatabases.database;
import java.io.*;
import java.sql.*;
public class TestDB {
public static void main(String[] args) throws Exception {
if (args.length == 0) {
System.out.println(
"Usage: java -classpath driver_class_path"
+ File.pathSeparator
+ ". TestDB propertiesFile");
return;
}
SimpleDataSource.init(args[0]);
Connection conn = SimpleDataSource.getConnection();
try {
Statement stat = conn.createStatement();
stat.execute("CREATE TABLE Test (Name VARCHAR(20))");
stat.execute("INSERT INTO Test VALUES ('Romeo')");
ResultSet result = stat.executeQuery("SELECT * FROM Test");
result.next();
System.out.println(result.getString("Name"));
stat.execute("DROP TABLE Test");
} finally {
conn.close();
}
}
}
package Chapter23RelationalDatabases.database;
import java.io.*;
import java.sql.*;
import java.util.Properties;
public class SimpleDataSource {
private static String url;
private static String username;
private static String password;
/**
* Initializes the data source.
* #param fileName the name of the property file that contains
* the database driver, URL, username, and password
*/
public static void init(String fileName) throws IOException, ClassNotFoundException {
Properties props = new Properties();
FileInputStream in = new FileInputStream(fileName);
props.load(in);
String driver = props.getProperty("jdbc.driver");
url = props.getProperty("jdbc.url");
username = props.getProperty("jdbc.username");
if (username == null)
username = "";
password = props.getProperty("jdbc.password");
if (password == null)
password = "";
if (driver != null)
Class.forName(driver);
}
/**
* Gets a connection to the database.
* #return the database connection
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
}
This is the contents of the database.properties file:
jdbc.url=jdbc:derby:BigJavaDB;create=true
This is the error stack when I try to run my program:
Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:derby:BigJavaDB;create=true
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at Chapter23RelationalDatabases.database.SimpleDataSource.getConnection(SimpleDataSource.java:42)
at Chapter23RelationalDatabases.database.TestDB.main(TestDB.java:20)
Why would you enter in anything into the "Shell Window" when you are using IntelliJ? you need to add derby jars to your class path, if you use maven you can simply add this:
<!-- APACHE DERBY - for an embedded database -->
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.10.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.10.1.1</version>
</dependency>
<!-- MYSQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.28</version>
</dependency>
Otherwise you can search for these yourself here http://mvnrepository.com/artifact/org.apache.derby/derby download the jars and add them to your class path manually which is what most beginners do. You can add jars to the classpath on the command line with the -cp flag but only use the command line with java to learn basic programming concepts. Other wise use a build tool like maven. I think you should maybe checkout some tutorial videos with adding jars to the classpath with IntelliJ/Eclipse/Netbeans. Then learn how to use maven, which I highly recommend as a beginner.

Categories

Resources