I bought the book Undocumented MATLAB by Yair Altmam; in chapter 2.2 of the book he discusses database connectivity and using the JDBC to connect to databases. I followed the steps and text of the book. I downloaded the mysql-connector-java-5.1.30-bin.jar(from http://dev.mysql.com/downloads/connector/j/) and typed up the following code as detailed in the book:
clear all
%%Initializing JDBC driver
try
import java.sql.DriverManager;
javaclasspath('mysql-connector-java-5.1.30-bin.jar')
driverClassName = 'com.mysql.jdbc.Driver';
try
%This works when the class/JAR is on the static Java classpath
%Note: driver automatically registers with DriverManager
java.lang.Class.forName(driverClassName);
catch
try
%Try loading from the dynamic Java path
classLoader = com.mathworks.jmi.ClassLoaderManager.getClassLoaderManager;
driverClass = classLoader.loadClass(driverClassName);
catch %#ok<*CTCH>
try
%One more attempt, using the system class-loader
classLoader = java.lang.ClassLoader.getSystemClassLoader;
%An alternative, using the MATLAB Main Thread's context
%classLoader =
%java.lang.Thread.currentThread.getContextClassLoader;
driverClass = classLoader.loadClass(driverClassName);
catch
%One final attempt-load directly, like this:
driverClass = eval(driverClassName); %#ok<*NASGU>
%Or like this (if the driver name is known in advance):
driverClass = com.mysql.jdbc.Driver;
end
end
%Now manually register the driver with the DriverManager
%Note: silently fails if driver is not in the static classpath
DriverManager.registerDriver(driverClass.newInstance);
end
%continue with database processing
catch
error(['JDBC driver ' driverClassName ' not found!']);
%do some failover activity
end
%% Connecting to a database
import java.sql.*;
connStr = 'jdbc:mysql://localhost:3306/test';
con = DriverManager.getConnection(connStr,'root','1234');
Every attempt to run the code I get the following error message:
??? Java exception occurred:
java.sql.SQLException: No suitable driver found for
jdbc:mysql://localhost:3306/test
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
Error in ==> undocumentedMATLAB at 45
con = DriverManager.getConnection(connStr,'root','1234');
Has anyone experienced this problem or have any suggestion that could help me resolve it.
Thanks in advance.
My first suspicion is your java class path. Instead of:
javaclasspath('mysql-connector-java-5.1.30-bin.jar')
Use
javaaddpath('C:\full\path\to\mysql-connector-java-5.1.30-bin.jar')
If that is not the problem, lets skip the DriverManager (doesn't really help much) and see if the code below works, (or where it fails).
d = com.mysql.jdbc.Driver;
urlValid = d.acceptsURL('jdbc:mysql://localhost:3306/test'); %Should return true
props = java.util.Properties;
props.put('user','root'); props.put('password','1234');
con = d.connect('jdbc:mysql://localhost:3306/test',props)
The DriverManager construct doesn't really help much. It seems to be designed to allow a developer to load up a bunch of drivers, and then connect to any supported database without knowing or caring what the DB implementation was (e.g. Mysql, Postgresql, Oracle etc.) I have never seen this as a useful feature. I think (hope?) that this is being used less in favor of a DataSource construct.
Regardless, if this is your first time connecting Mysql to Matlab, you probably are best just directing using the provided Driver class.
Related
I am trying to connect to Hive2 server via JDBC with kerberos authentication. After numerous attempts to make it work, I can't get it to work with the Cloudera driver.
If someone can help me to solve the problem, I can greatly appreciate it.
I have this method:
private Connection establishConnection() {
final String driverPropertyClassName = "driver";
final String urlProperty = "url";
Properties hiveProperties = config.getMatchingProperties("hive.jdbc");
String driverClassName = (String) hiveProperties.remove(driverPropertyClassName);
String url = (String) hiveProperties.remove(urlProperty);
Configuration hadoopConfig = new Configuration();
hadoopConfig.set("hadoop.security.authentication", "Kerberos");
String p = config.getProperty("hadoop.core.site.path");
Path path = new Path(p);
hadoopConfig.addResource(path);
UserGroupInformation.setConfiguration(hadoopConfig);
Connection conn = null;
if (driverClassName != null) {
try {
UserGroupInformation.loginUserFromKeytab(config.getProperty("login.user"), config.getProperty("keytab.file"));
Driver driver = (Driver) Class.forName(driverClassName).newInstance();
DriverManager.registerDriver(driver);
conn = DriverManager.getConnection(url, hiveProperties);
} catch (Throwable e) {
LOG.error("Failed to establish Hive connection", e);
}
}
return conn;
}
URL for the server, that I am getting from the properties in the format described in Cloudera documentation
I am getting an exception:
2018-05-05 18:26:49 ERROR HiveReader:147 - Failed to establish Hive connection
java.sql.SQLException: [Cloudera][HiveJDBCDriver](500164) Error initialized or created transport for authentication: Peer indicated failure: Unsupported mechanism type PLAIN.
at com.cloudera.hiveserver2.hivecommon.api.HiveServer2ClientFactory.createTransport(Unknown Source)
at com.cloudera.hiveserver2.hivecommon.api.ZooKeeperEnabledExtendedHS2Factory.createClient(Unknown Source)
...
I thought, that it is missing AuthMech attribute and added AuthMech=1 to the URL. Now I am getting:
java.sql.SQLNonTransientConnectionException: [Cloudera][JDBC](10100) Connection Refused: [Cloudera][JDBC](11640) Required Connection Key(s): KrbHostFQDN, KrbServiceName; [Cloudera][JDBC](11480) Optional Connection Key(s): AsyncExecPollInterval, AutomaticColumnRename, CatalogSchemaSwitch, DecimalColumnScale, DefaultStringColumnLength, DelegationToken, DelegationUID, krbAuthType, KrbRealm, PreparedMetaLimitZero, RowsFetchedPerBlock, SocketTimeOut, ssl, StripCatalogName, transportMode, UseCustomTypeCoercionMap, UseNativeQuery, zk
at com.cloudera.hiveserver2.exceptions.ExceptionConverter.toSQLException(Unknown Source)
at com.cloudera.hiveserver2.jdbc.common.BaseConnectionFactory.checkResponseMap(Unknown Source)
...
But KrbHostFQDN is already specified in the principal property as required in the documentation.
Am I missing something or is this documentation wrong?
Below is the one of the similar kind of problem statement in Impala (just JDBC engine changes others are same) that is resolved by setting "KrbHostFQDN" related properties in JDBC connection string itself.
Try to use the URL below. Hopefully works for u.
String jdbcConnStr = "jdbc:impala://myserver.mycompany.corp:21050/default;SSL=1;AuthMech=1;KrbHostFQDN=myserver.mycompany.corp;KrbRealm=MYCOMPANY.CORP;KrbServiceName=impala"
I suppose that if you are not using SSL=1 but only Kerberos, you just drop that part from the connection string and don't worry about setting up SSL certificates in the java key store, which is yet another hassle.
However in order to get Kerberos to work properly we did the following:
Install MIT Kerberos 4.0.1, which is a kerberos ticket manager. (This is for Windows)
This ticket manager asks you for authentication every time you initiate a connection, creates a ticket and stores it in a kerberos_ticket.dat binary file, whose location can be configured somehow but I do not recall exactly how.
Finally, before launching your JAVA app you have to set an environment variable KRB5CCNAME=C:/path/to/kerberos_ticket.dat. In your java app, you can check that the variable was correctly set by doing System.out.println( "KRB5CCNAME = " + System.getenv( "KRB5CCNAME" ) ). If you are working with eclipse or other IDE you might even have to close the IDE,set up the environment variable and start the IDE again.
NOTE: this last bit is very important, I have observed that if this variable is not properly set up, the connection wont be established...
In Linux, instead MIT Kerberos 4.0.1, there is a program called kinit which does the same thing, although without a graphical interface, which is even more convenient for automation.
I wanted to put it in the comment but it was too long for the comment, therefore I am placing it here:
I tried your suggestion and got another exception:
java.sql.SQLException: [Cloudera]HiveJDBCDriver Error
creating login context using ticket cache: Unable to obtain Principal
Name for authentication .
May be my problem is, that I do not have environment variable KRB5CCNAME set.
I, honestly, never heard about it before.
What is supposed to be in that ticket file.
I do have, however, following line in my main method:
System.setProperty("java.security.krb5.conf", "path/to/krb5.conf");
Which is supposed to be used by
UserGroupInformation.loginUserFromKeytab(config.getProperty("login.user"), config.getProperty("keytab.file"));
to obtain the kerberos ticket.
To solve this issue update Java Cryptography Extension for the Java version that you use in your system.
Here's the link when you can download JCE for Java 1.7
Uncompress and overwrite those files in $JDK_HOME/jre/lib/security
Restart your computer.
I know this has been asked a hundred times and I think I have read all the posts and tried every variation of the solutions. I'm using NetBeans and new to it. I'm sure I'm just missing some small step because it seems like its just not seeing the driver that I added to the library. This is the first time I have tried to connect to a database so please be gentle.
try
{
String host = "jdbc:sqlserver://Server:1433;Database";
String uName = "User";
String uPass = "Password";
Connection con = DriverManager.getConnection(host,uName,uPass);
System.out.println("Your are connected to SQLServer 2014");
}
catch (SQLException err)
{
System.out.println(err.getMessage());
}
You forgot to register the jdbc driver class.
Call
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
before calling Connection con = DriverManager.getConnection(host,uName,uPass);.
It will resolve the issue.
UPDATE
In documentation for new jdbc drivers it is declared that this step is not necessary. But in practical work, I have found that this step is required even for new drivers, otherwise you will get "No suitable driver found" error. This error occurs sometimes, for example it does not occur when you are making and running a console jar-application, but occurs when you have created and deployed a web-application.
So, I advise to register the jdbc driver class before getting the database connection via DriverManager.getConnection() call.
In java I am trying to connect with Sybase database through java program as shown below
public static void connect() {
SybDriver sybDriver = null;
Connection conn;
try {
sybDriver = (SybDriver) Class.forName(
// "com.sybase.jdbc3.jdbc.SybDriver").newInstance();
"com.sybase.jdbc2.jdbc.SybDriver").newInstance();
System.out.println("Driver Loaded");
conn = DriverManager.getConnection(url, username, password);
boolean isTrue = conn.isValid(3);
System.out.println(isTrue);
But i am getting the below exception
Driver Loaded
Exception in thread "main" java.lang.AbstractMethodError: com.sybase.jdbc2.jdbc.SybConnection.isValid(I)Z
at connectionTry.connect(connectionTry.java:97)
at connectionTry.main(connectionTry.java:23)
I have done analysis in google what i have to came up to know jconnn.jar is missing as the issue is the method isValid(I)Z is not there in jconn2.jar is not there please advise how to overcome from this error please.
The driver you are using is - based on the class name in the stacktrace - a JDBC 2 driver. The isValid method was added in Java 6 (or: JDBC 4), so you can't use it with a driver that doesn't implement it.
You either need to upgrade to a newer driver: contact Sybase for that, or simply not call the isValid method. In the code you show there is no reason to call it: you just created the connection, of course it is valid. This method is intended to check the validity of long-living connections (eg in the context of a connection pool).
AbstractMethodError is thrown when the implementation class doesn't comply to the signature defined in the abstract class. Use a compatible version of the implementation or alternatively avoid the methods that conflict.
Ideally latest version of drivers must be having matching implementations or you will have to contact sybase to fix that.
I am trying to connect to a database in Mariadb through a simple java application but the connection is told to be unsuccessful and an Exception is thrown. I have done the similar connection using mysql and it was working correctly. The problem is maybe with the driver here.
try{
Class.forName("org.mariadb.jdbc.Driver");
Connection connection = DriverManager.getConnection(
"jdbc:mariadb://localhost:3306/project", "root", "");
Statement statement = connection.createStatement();
String uname="xyz",pass="abc";
statement.executeUpdate("insert into user values('"+uname+"','"+pass+"')");}//end of try block
I looked up the internet for the help and came by that driver class provided by the MariaDB Client Library for Java Applications is not com.mysql.jdbc.Driver but org.mariadb.jdbc.Driver! I changed it accordingly but it seems the problem is with the very first line inside the try block. The driver is not loading at all.
Also, I have added the mysql jar file to the libraries of my java application as in the screen-shot below. Please help me through this.
It appears that you are trying to use jdbc:mariadb://... to establish a connection to a MariaDB server instance using the MySQL JDBC Driver. That probably won't work because the MySQL JDBC Driver would use jdbc:mysql://..., regardless of whether it is connecting to a MySQL server or a MariaDB server. That is, the connection string must match the driver that is being used (rather than the database server being accessed).
The MySQL and MariaDB drivers are supposed to be somewhat interchangeable, but it only seems prudent to use the MariaDB connector when accessing a MariaDB server. For what it's worth, the combination of mariadb-java-client-1.1.7.jar
and
Connection con = DriverManager.getConnection(
"jdbc:mariadb://localhost/project",
"root",
"whatever");
worked for me. I downloaded the MariaDB Client Library for Java from here:
https://downloads.mariadb.org/client-java/1.1.7/
which I arrived at via
https://downloads.mariadb.org/
Additional notes:
There is no need for a Class.forName() statement in your Java code.
The default configuration for MariaDB under Mageia may include the skip-networking directive in /etc/my.cnf. You will need to remove (or comment out) that directive if you want to connect to the database via JDBC because JDBC connections always look like "network" connections to MySQL/MariaDB, even if they are connections from localhost. (You may need to tweak the bind-address value to something like 0.0.0.0 as well.)
An additional note:
Exploring the MariaDB JDBC driver, I found this inside the url parsing file:
Project: https://github.com/MariaDB/mariadb-connector-j.git
File: src/main/java/org/mariadb/jdbc/UrlParser.java
public static UrlParser parse(final String url, Properties prop) throws SQLException {
....
if (url.startsWith("jdbc:mysql:")) {
UrlParser urlParser = new UrlParser();
parseInternal(urlParser, url, prop);
return urlParser;
} else {
if (url.startsWith("jdbc:mariadb:")) {
UrlParser urlParser = new UrlParser();
parseInternal(urlParser, "jdbc:mysql:" + url.substring(13), prop);
return urlParser;
}
}
As you can see, the string "jdbc:mariadb:" is always replaced with "jdbc:mysql:" internally. So when it comes to the MariaDB driver, whether it is :mariadb: or :mysql: it always gets parsed as "jdbc:mysql:".
No difference.
if (url.startsWith("jdbc:mariadb:")) {
....
parseInternal(urlParser, "jdbc:mysql:" + url.substring(13), prop);
....
java to mysql connection code:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
System.out.println("Driver loaded");
con = DriverManager.getConnection(url, "root", "sai");
stmt = con.createStatement();
System.out.println("Connection established");
after excution of above code
"Driver loaded" message printed on console but,
after that following exception is printed -
[Microsoft][ODBC Driver Manager]
Data source name not found and no default driver specified
i have already create DSN(MYSQL ODBC 3.51 Driver) for project
Please tell me solution of above problem.
"If somehow possible, don't use a JdbcOdbc driver, but a pure JDBC-Driver for your database!"
An example MySql pure JDBC-Driver would be the com.mysql.jdbc.Driver class found in the mysql-connector-java-5.x.x.jar file available for download from MySQL.
A good explanation of the differences between JDBC and JDBC-ODBC are available on wikipedia
If somehow possible, don't use a JdbcOdbc driver, but a pure JDBC-Driver for your database!
For the question of how to register the driver, from the javadocs for java.sql, Interface Driver:
It is strongly recommended that each
Driver class should be small and
standalone so that the Driver class
can be loaded and queried without
bringing in vast quantities of
supporting code.
When a Driver class is loaded, it
should create an instance of itself
and register it with the
DriverManager. This means that a user
can load and register a driver by
calling
Class.forName("foo.bah.Driver")
A separate call to 'newInstance' or registerDriver' is Cargo-Cult-programming.
It's a while since I've done this, but you could try to explicitly register your driver with the DriverManager class. This means that you're not depending upon something unseen implicitly happening in the background.
DriverManager.registerDriver((Driver)
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance());
con = DriverManager.getConnection(url, "root", "sai");
This will ensure that the "sun.jdbc.odbc.JdbcOdbcDriver" class is loaded and connected to the DriverManager.