Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to figure out the best approach for using hikaricp (JDBC connection pool) with microsoft sql server. From what I saw, the DataSource option is recommended (as is the case for most connection pools I've seen). However, I was not able to form a connection correctly with the sql server database based on the examples I've seen - wondering if anyone has a working example to which I can plug my DB info into.
Make sure you have taken the following steps:
If using maven, make sure that you have the following dependency in your pom file (if using JDK7/8):
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.0.1</version>
<scope>compile</scope>
</dependency>
If using another build tool, change the resource URL accordingly (or just download the jar file from the maven repository if there is no other option for you).
I believe you need the sqljdbc4.jar file in your pom file as well (I could be wrong about this requirement so I may update the post once I reconfirm)
Import the following in your class along with other references:
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
Add the following final properties (or simply load them from config file):
private final String url = "jdbc:sqlserver://";
private final String serverName= "xxx.xxx.xxx.xxx";
private final int portNumber = 1433;
private final String databaseName= "ACTUALDBNAME";
private final String userName = "ACTUALUSERNAME";
private final String password = "ACTUALPASSWORD";
private final String selectMethod = "cursor";
You can retrieve the connection URL like this:
public String getConnectionUrl() {
return url+this.serverName+":"+this.portNumber+";databaseName="+this.databaseName+";user="+this.userName+";password="+this.password+";selectMethod="+this.selectMethod+";";
}
Then, the following should give you the DataSource you need in order to get a connection:
public DataSource getDataSource() {
final HikariDataSource ds = new HikariDataSource();
ds.setMaximumPoolSize(10);
ds.setDataSourceClassName("com.microsoft.sqlserver.jdbc.SQLServerDataSource");
// ds.addDataSourceProperty("serverName", this.serverName);
//ds.addDataSourceProperty("databaseName", this.databaseName);
ds.addDataSourceProperty("url", this.getConnectionUrl());
ds.addDataSourceProperty("user", this.userName);
ds.addDataSourceProperty("password", this.password);
ds.setInitializationFailFast(true);
ds.setPoolName("wmHikariCp");
return ds;
}
or
public DataSource getDataSource() {
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(10);
config.setDataSourceClassName("com.microsoft.sqlserver.jdbc.SQLServerDataSource");
config.addDataSourceProperty("serverName", this.serverName);
config.addDataSourceProperty("port", this.portNumber);
config.addDataSourceProperty("databaseName", this.databaseName);
config.addDataSourceProperty("user", this.userName);
config.addDataSourceProperty("password", this.password);
return new HikariDataSource(config); //pass in HikariConfig to HikariDataSource
}
The preferred route is to pass the HikariConfig to the HikariDataSource constructor. You can also load the config from a properties file.
Then get connection from the datasource:
Connection con = null;
con = ds.getConnection(); //where ds is the dataSource retrieved from step 5
Related
I have a use case where the Saprk Data Set API has to connect to SQL server using jdbc to retrieve the data.
The DB is supporting the kerberos authentication thats why using Spring JTDS driver.
The code for JDBC connectivity is as :
/**
* Returns the data source for db connection
* #return
* #throws Exception
*/
private static DriverManagerDataSource getDataSource() throws Exception {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("net.sourceforge.jtds.jdbc.Driver");
String dataSourceUrl = "jdbc:jtds:sqlserver://" + "DBDEV.abc.com" + "/"
+ "TestDB";
dataSource.setUrl(dataSourceUrl);
Properties connProps = new Properties();
connProps.setProperty(DescapDataConstants.APP_NAME_PROPERTY, "Test");
connProps.setProperty(DescapDataConstants.USE_KERBEROS, Boolean.TRUE.toString());
connProps.setProperty(DescapDataConstants.LOGIN_TIMEOUT, "60");
connProps.setProperty(DescapDataConstants.SOCKET_TIMEOUT, "7200");
dataSource.setConnectionProperties(connProps);
return dataSource;
}
But there is no provision to use this Data source as per Spark JDBC API when checked on this page :
https://spark.apache.org/docs/2.3.1/api/java/org/apache/spark/sql/DataFrameReader.html#jdbc-java.lang.String-java.lang.String-java.util.Properties-
Is there any way to use Data Source for connecting to the JDBC via Spark API's.
As already noted in the comments and from a quick look at the source code here, it looks like the implementation does not indeed support a datasource lookup.
One option is to extend below source code and to extend it to accept a connection object itself and to figure out error handling and remember to close it!
I am trying to connect Sybase which has set encrypt_password property to true. The JTDS version I am using is newest version I can find in Maven: 1.3.1 released in 2013 Jun.
I am getting error:ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Adaptive Server requires encryption of the login password on the network
Here is the DB Config code:
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(dbConn.getDriverClassName());
dataSource.setUrl(dbConn.getUrl());
dataSource.setUsername(dbConn.getUsername());
dataSource.setPassword(dbConn.getPassword());
// setting driver properties
Properties props = new Properties();
for(String propPair: dbConn.getDriverProperties().split(",")) {
String[] prop = propPair.split("=");
props.setProperty(prop[0], prop[1]);
}
dataSource.setConnectionProperties(props);
return dataSource;
}
and in application.yml file:
connection:
driverProperties: "ENCRYPT_PASSWORD=true"
However this still does not work and I am getting this error:
ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Adaptive Server requires encryption of the login password on the network
I have made some search but the answer people left seems frustrating:
https://sourceforge.net/p/jtds/discussion/104389/thread/90e1bb7f/
Is there anyway I can do this property manually? Thanks in advance for reading this question and potentially if you have the answer.
As part of securing all the connection we are enabling ASO in Oracle database, i was able to make secure connection from my java using oracle.jdbc.pool.OracleDataSource. But we have projects using apache basic datasource. I tried the below but still the data is not getting encrypted.
BasicDataSource ods = new BasicDataSource();
ods.setUrl(URL);
ods.setUsername(user);
ods.setPassword(password);
ods.setConnectionProperties("AutoCommit=false;");
ods.setConnectionProperties("OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL=REQUIRED;");
ods.setConnectionProperties("OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES=(AES256);");
ods.setConnectionProperties("OracleConnection.CONNECTION_PROPERTY_THIN_NET_CRYPTO_SEED=(sfdsvcfdssegdsvg);");
Please let me know if I am missing something in the connection properties. Thanks.
Method BasicDataSource#setConnectionProperties(String) overrides all properties that been added to the DataSource previously
You need to use method BasicDataSource#addConnectionProperty(String, String) to add single property:
BasicDataSource ods = new BasicDataSource();
ods.addConnectionProperty("OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL", "REQUIRED")
or build Properties instance with relevant data, and only then add it to the DataSource:
Properties prop = new Properties();
prop.setProperty("OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL", "REQUIRED");
prop.setProperty("OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES", "(AES256)")
...
BasicDataSource ods = new BasicDataSource();
ods.setConnectionProperties(prop);
I have created java web application in eclipse with database mysql.But now i have to deploy that web application in tomcat server.I know how to deploy web application without databas but need assistance with database.
Thank you in advance.
There are two main ways to obtain JDBC connections within a Java Web Application.
Retrieve a connection from a DataSource registered in a JNDI directory service within the container.
Creating a Connection manually within your application code.
JNDI
Using JNDI requires a connection pool to be created within tomcat. This can be done within the context.xml file in tomcat's config directory.
Example Context.xml Entry
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="dbusername"
password="dbpassword"
driverClassName="org.hsql.jdbcDriver"
url="jdbc:HypersonicSQL:database"
maxActive="8"
maxIdle="4"/>
This connection would then be retrieved in your code as follows:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
envCtx.lookup("jdbc/EmployeeDB");
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();
Manual Creation
Manually creating the connection within your code is simpler, however JNDI is recommended for its portability.
Manual Example
public class MysqlConnect{
public static void main(String[] args) {
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/";
String dbName = "jdbctutorial";
String driver = "com.mysql.jdbc.Driver";
String userName = "root";
String password = "root";
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url+dbName,userName,password);
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
When deploying for either of these scenarios it is important that you have the appropriate JDBC driver in your classpath.
There are 2 scenarios here:
You define the connection directly in the code using simple JDBC and Class.forName() - in that case you just need to make sure the jar containing the driver is in the classpath and it should work.
This is the preferred method - Define a Datasource on the server and call it in the code by using the JNDI API:
InitialContext ic = new InitialContext();
DataSource ds = (DataSource)ic.lookup("jdbc/testDS");
conn = ds.getConnection();
in contex.xml using -- tag we can connect to any db
I'm trying to follow Java's JDBC tutorials to write a Java program that can connect to SQL Server 2008. I'm getting lost at the point of making a connection.
The following snippet is from the tutorial:
InitialContext ic = new InitialContext();
DataSource ds = ic.lookup("java:comp/env/jdbc/myDB");
Connection con = ds.getConnection();
DataSource ds = (DataSource) org.apache.derby.jdbc.ClientDataSource()
ds.setPort(1527);
ds.setHost("localhost");
ds.setUser("APP")
ds.setPassword("APP");
Connection con = ds.getConnection();
There's no explanation of what comp/env/jdbc/myDB should point to, and I don't know how I should choose a port. Also, the object ds seems to be defined twice.
I'm using the JSQLDataSource driver, for the record. Can anyone point me in the right direction here?
http://java.sun.com/docs/books/tutorial/jdbc/basics/connecting.html
I'm not sure anyone above has really answered the question.
I found this microsoft sample useful.
The key information in there is really that the class you need is SQLServerDataSource
that is basically a configuration object - you use it something like this:
SQLServerDataSource dataSource = new SQLServerDataSource();
dataSource.setUser("aUser");
dataSource.setPassword("password");
dataSource.setServerName("hostname");
dataSource.setDatabaseName("db");
You would then call
dataSource.getConnection();
to get a connection object which is basically the thing you use to talk to the database.
Use
connection.prepareStatement("some sql with ? substitutions");
to make something for firing off sql and:
connection.prepareCall
for calling stored procedures.
Start with the JDBC tutorial or the Microsoft docs.
and this:
String driver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
Class.forName(driver);
String url = "jdbc:microsoft:sqlserver://host:1433/database";
Connection conn = DriverManager.getConnection(url, "username", "password");
Fill in your values for host, database, username, and password. The default port for SQL server is 1433.
UPDATE: Good point below. JDBC drivers can be had from both Microsoft and jTDS. I prefer the latter.
JNDI lookups have to do with Java EE app servers that support connection pooling. You can ask the app server to create a pool of connections, which can be an expensive thing to do, and loan them out to clients like library books as needed.
If you aren't using a Java EE app server or connection pooling, you have to create the connection on your own. That's where manual processes and DriverManager come in.
EXPLANATION: As for why the Sun tutorial shows DataSource twice, I'd say it's a case of poor editing. If you look above the code sample it says you can get a DataSource "by lookup or manually". The code snippet below shows both together, when it should be one or the other.
You know it's an inadvertent error because there's no way the code as written could compile. You have "ds" declared twice.
So it should read "...lookup", followed by its code snippet, and then "...manually", followed by its code snippet.
I like the jTDS driver for connecting to SQL Server. A URL will look like this:
jdbc:jtds:sqlserver://localhost/Finance;instance=sqlexpress
Check this for jTDS Url Info.
This also has some interesting information to help troubleshoot jtds to sql express sorts of problems.
DataSource ds = new SimpleDriverDataSource(new com.mysql.jdbc.Driver(),
"jdbc:mysql://database:1433;databaseName=name", "username", "password");
JdbcTemplate jdbc = new JdbcTemplate(ds);
This question has already been answered long time ago. The question was asked about JNDI lookup. With lookup you have to see the application server log to see what the connection is bound to. For example in Jboss startup, I can see:
[ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=myDB' to JNDI name 'java:myDB'
Using that name=myDB you lookup
InitialContext ic = new InitialContext();
DataSource ds = ic.lookup("java:myDB");
Notice how the server log and the code both point to the JNDI name java:myDB.