connection error with db2 jdbc - java

Can anyone offer a clue on how to diagnose the error listed below? Note, I CAN connect to this DB2 instance via DB2 connect, but not thru jdbc.
org.apache.openjpa.persistence.PersistenceException: Unable to open a test
connection to the given database. JDBC url = jdbc:db2://dxxx_xxx.xxx.com:5000/XXXXX:deferPrepares=false, username = NNNNN. Terminating connection pool. Original Exception: ------
com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][10165][10051][3.63.75] Invalid database URL syntax: jdbc:db2:/dxxx_xxx.xxx.com:5000/XXXXX:deferPrepares=false. ERRORCODE=-4461, SQLSTATE=42815
at com.ibm.db2.jcc.am.fd.a(fd.java:679)
at com.ibm.db2.jcc.am.fd.a(fd.java:60)
at com.ibm.db2.jcc.am.fd.a(fd.java:85)
at com.ibm.db2.jcc.DB2Driver.tokenizeURLProperties(DB2Driver.java:911)
at com.ibm.db2.jcc.DB2Driver.connect(DB2Driver.java:408)
at java.sql.DriverManager.getConnection(DriverManager.java:571)
at java.sql.DriverManager.getConnection(DriverManager.java:215)
at com.jolbox.bonecp.BoneCP.obtainRawInternalConnection(BoneCP.java:256)
at com.jolbox.bonecp.BoneCP.<init>(BoneCP.java:305)
at com.jolbox.bonecp.BoneCPDataSource.maybeInit(BoneCPDataSource.java:150)

The error message is pretty self-explanatory:
Invalid database URL syntax
You must not have any spaces in the URL, and key-value pairs are separated with semicolons, not commas. Note that you must put a semicolon after the last value too.
jdbc:db2://dxxx_xxx.xxx.com:5000/XXXXX:deferPrepares=false;username=NNNNN;
Details can be found in the manual.

Take a look at this information taken from the DB2 documentation (added link of the reference below).
Message text: text-from-getMessage
Explanation: The specified value is invalid or out of range.
User response: Call SQLException.getMessage to retrieve specific information about the problem.
SQLSTATE: 42815
Reference: https://www.ibm.com/support/knowledgecenter/SSEPGG_9.7.0/com.ibm.db2.luw.apdv.java.doc/src/tpc/imjcc_rjvjcsqc.html

Related

DB2OLEDB Driver and error messages in SQLException from SQL Server 2016

We are using SQL Server 2016 with a linked server to zDB2 (mainframe) via Microsoft OLE DB Provider for DB2 Version 5.0.
When executing a failing SQL statement remote on a linked server (zDB2) the error description is clear in SQL studio but useless in Java.
Example of statement (missing schema name):
EXEC (N'UPDATE TABLENAME SET COLUMN1=''SOMEVALUE'' WHERE COLUMN2= ''032'' ') AT ZDB2
Gives the following result in SQL Studio:
OLE DB provider "DB2OLEDB" for linked server "ZDB2" returned message "DB2GRP.TABLENAME IS AN UNDEFINED NAME SQLSTATE: 42704, SQLCODE: -204".
Msg 7215, Level 17, State 1, Line 6
Could not execute statement on remote server 'ZDB2'.
But the following result in a Java SQLException:
com.microsoft.sqlserver.jdbc.SQLServerException: Could not execute statement on remote server 'ZDB2'.
SQL State: S0001
SQL Error code: 7215
Using a debugger and inspecting the SQL Exception object, it seems the SQLException has no other data on the error.
How can I get a more useful explanation out of the SQLException on what went wrong besides "Could not execute statement on remote server" ?
And where is the documentation of what S0001 and 7215 means ? (I already googled)
Thank you in advance.
I believe the S0001 and 7215 are responses back from the Microsoft JDBC driver. The DB2 error info is "SQLSTATE: 42704, SQLCODE: -204" which is unfortunately not showing up in the Java output. It looks like the Microsoft driver is substituting it's own sqlstate/code instead of passing along DB2's.
The -204 is "name is an undefined name" (as is stated in the text before the sqlstate and code).
http://www.ibm.com/support/knowledgecenter/SSEPEK_10.0.0/codes/src/tpc/db2z_n.html
Since you mention Java code, note that DB2 provides a JDBC driver for direct connectivity. That should at least eliminate the possibility of the MS driver interfering with the error codes returned by DB2. You typically have to get the driver and license file from your systems guys--AFAIK, they aren't publicly provided by IBM but they are included with DB2 for z/OS. But I'd recommend trying to use the IBM driver unless there's some compelling reason why you have to use the Microsoft driver--I am confused about the mention of both OLE DB Provider and JDBC.
Apparently errors from a linked server are stored as warnings on the statement rather than part of the SQLException when using Microsofts JDBC Driver.
This is how i did it:
try{
...
} catch (SQLException e) {
SQLWarning sqlWarning = currentStatement.getWarnings();
if (sqlWarning != null) {
warning = sqlWarning.getMessage();
}
}

How to pass session variables in JDBC url properly?

I have to increase group_concat_max_len.
I cannot do it by preparestatement, and also I cannot do it in mysql my.conf file.
I found on mysql docs that there is an option to pass session variables in url.
But there is no example, I tried to do it like that:
jdbc.url=jdbc:mysql://xxxx.xx.xx.xx/dbName?sessionVariables=group_concat_max_len:204800
and I have this exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':204800' at line 1
And also I tried it like like this:
jdbc.url=jdbc:mysql://xxxx.xx.xx.xx/dbName?sessionVariables=group_concat_max_len,204800
because the official docs says:
sessionVariables
A comma-separated list of name/value pairs to be sent as SET SESSION ... to the server when the driver connects.
Since version: 3.1.8
Any ideas???
Try this:
jdbc.url=jdbc:mysql://xxxx.xx.xx.xx/dbName?sessionVariables=group_concat_max_len=204800
If you need to add more than one session parameter you can do it like this:
jdbc:mysql://localhost/database?sessionVariables=FOREIGN_KEY_CHECKS=0&sessionVariables=SQL_SAFE_UPDATES=0
The MySQL Connector/J Configuration Properties documentation has been updated since with a better description, especially when it comes to setting multiple system variables in the connection URL :
sessionVariables
A comma or semicolon separated list of name=value pairs to be sent as
SET [SESSION] ... to the server when the driver connects.
Since version: 3.1.8
Which results in URLs like this one :
jdbc:mysql://xxxx.xx.xx.xx/dbName?sessionVariables=group_concat_max_len=204800,bulk_insert_buffer_size=42
Semicolons can be used instead of commas. A mix of the two can be used within the same URL.
This will only work for system variables that have a SESSION scope (you can find out which ones can be set at SESSION-level by looking at the list of Server System Variables).
The connection will fail if the variable doesn't exist, if it is not a server system variable or if its scope is GLOBAL-only.

Heroku won't accept needed URL argument to prevent MySql zeroTimeBehavior error

I've developed a Play/Scala application that runs on my local MySql. But a needed database URL argument, zeroDateTimeBehavior=convertToNull (Java TimeStamp) gets mangled by some further concatination of the URL that Heroku does and so my app can't get a connection to ClearDB (the Heroku MySql offering).
Here is my DB URL:
db.default.url="mysql://be32d43afc3cb7:c73c404d#us-cdbr-east-03.cleardb.com/heroku_6cf0eb306e78bc8?reconnect=true&zeroDateTimeBehavior=convertToNull"
and the subsequent Heroku version that it transmogrifies:
JDBC URL = jdbc:mysql://us-cdbr-east-03.cleardb.com/heroku_6cf0eb306e78bc8?reconnect=true&zeroDateTimeBehavior=convertToNull?useUnicode=yes&characterEncoding=UTF-8&connectionCollation=utf8_general_ci
Something mysterious is going on with the ? and & deliminators.
Heroku says the error is caused by:
java.sql.SQLException: The connection property 'zeroDateTimeBehavior' only accepts values of the form: 'exception', 'round' or 'convertToNull'. The value 'convertToNull?useUnicode=yes' is not in this set.
So, is there some other way I can configure this argument? Without it, I get this error:
play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp]]
This strike a bell with anybody? Much thanks to anyone who can shed some light.
EDIT/SOLUTION:
Heroku also concatenates several args to the DB URL that they provide users. Because of Heroku's use concatenation of "?" before their own set of args, attempting to add my own args to the DB URL will not work. However I found a different solution which seems to work equally well.
SET sql_mode = 'NO_ZERO_DATE';
I put this in my table descriptions and it solved the problem of
'0000-00-00 00:00:00' can not be represented as java.sql.Timestamp

Odd Oracle connection URL

One of our customers is trying to connect to an Oracle database with the following JDBC URL:
jdbc:oracle:thin:#(DESCRIPTION=(FAILOVER=ON)LOAD_BALANCE=OFF)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=server1.domain.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=server2.domain.com)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=FOO)))
They get this error:
Caused by: oracle.net.ns.NetException: NL Exception was generated
at oracle.net.resolver.AddrResolution.resolveAddrTree(AddrResolution.java:614) ~[ojdbc5_11g-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:411) ~[ojdbc5_11g-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:672) ~[ojdbc5_11g-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:237) ~[ojdbc5_11g-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1042) ~[ojdbc5_11g-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:301) ~[ojdbc5_11g-11.2.0.1.0.jar:11.2.0.1.0]
Questions:
I've never seen such a connection URL before. It looks more like an entry in TNSNAMES.ORA. How can I find out what this connection string means?
What could be causing this useless error message?
The syntax is the 'Oracle Net connection descriptor syntax', see table 8.3 in the JDBC Developers Guide.
The syntax is indeed the same as the syntax used in tnsnames.ora; this syntax is described in the Oracle Database Net Services Reference.
As to the specific issue, it looks to me like you have unbalanced parentheses in the descriptor, specifically:
(FAILOVER=ON)LOAD_BALANCE=OFF)
Should be:
(FAILOVER=ON)(LOAD_BALANCE=OFF)
(note the additional (.)
I generated the following connection URL from your tnsnames entry :
jdbc:oracle:thin:#server1.domain.com:1521/FOO
try to use the above connection URL.
Also do check if the listener is up and running :
in windows : ctrl + r, services.msc, check whether service : "Oracle*TNSListener" is started.
jdbc:oracle:thin:#(DESCRIPTION=(FAILOVER=ON)LOAD_BALANCE=OFF)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=server1.domain.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=server2.domain.com)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=FOO)))

Call to DataSource.getConnection not returning the expected connection

I have the following code:
Hashtable env1 = new Hashtable();
env1.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
log.info("Executed step 1");
env1.put(javax.naming.Context.PROVIDER_URL, "iiop://myhost.com:9301");
log.info("Executed step 2");
Context ctx = new InitialContext(env1);
DataSource ds = (DataSource)ctx.lookup("jdbc/mydatasource");
log.info("Excecuted lookup ="+ds);
conn = ds.getConnection();
I have the previous code in an standalone application that is connecting to WAS 6.1.0.3 in order to retrieve a connection from the datasource. The code is very straighforward, and I have seen the same code working in a different environment, but in this case when I call getConnection I get an exception. The datasource is WAS has the proper authentication alias set and when the connection is tested it works OK from the WAS side, but the previous code won't work.
If I change this line: conn = ds.getConnection();
to this: conn = ds.getConnection("username","password");
Then the code will work! But that's not what I want since the connections in the datasource should already have the credentials set. I was initially thinking this was a Sybase problem, but it's also happening with Oracle, so would rather say I have a problem with WAS.
If you are curious about the exceptions, for Sybase I get:
java.sql.SQLException: JZ004: User name property missing in DriverManager.getConnection(..., Properties).DSRA0010E: SQL State = JZ004, Error Code = 0
at com.sybase.jdbc2.jdbc.ErrorMessage.raiseError(ErrorMessage.java:569)
at com.sybase.jdbc2.tds.LoginToken.<init>(LoginToken.java:128)
at com.sybase.jdbc2.tds.Tds.doLogin(Tds.java:506)
at com.sybase.jdbc2.tds.Tds.login(Tds.java:449)
at com.sybase.jdbc2.jdbc.SybConnection.tryLogin(SybConnection.java:254)
at com.sybase.jdbc2.jdbc.SybConnection.regularConnect(SybConnection.java:230)
at com.sybase.jdbc2.jdbc.SybConnection.<init>(SybConnection.java:200)
at com.sybase.jdbc2.jdbc.SybPooledConnection.<init>(SybPooledConnection.java:72)
at com.sybase.jdbc2.jdbc.SybConnectionPoolDataSource.createConnection(SybConnectionPoolDataSource.java:138)
at com.sybase.jdbc2.jdbc.SybDriver.connect(SybDriver.java:485)
at com.sybase.jdbc2.jdbc.SybDriver.connect(SybDriver.java:517)
at com.sybase.jdbc2.jdbc.SybDataSource.getConnection(SybDataSource.java:227)
at com.sybase.jdbc2.jdbc.SybConnectionPoolDataSource.getPooledConnection(SybConnectionPoolDataSource.java:74)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper$1.run(InternalGenericDataStoreHelper.java:897)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper.getPooledConnection(InternalGenericDataStoreHelper.java:892)
at com.ibm.ws.rsadapter.spi.WSRdbDataSource.getPooledConnection(WSRdbDataSource.java:1181)
at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.createManagedConnection(WSManagedConnectionFactoryImpl.java:1047)
at com.ibm.ws.rsadapter.spi.WSDefaultConnectionManagerImpl.allocateConnection(WSDefaultConnectionManagerImpl.java:81)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:431)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:400)
And for Oracle I get this one:
java.sql.SQLException: invalid arguments in callDSRA0010E: SQL State = null, Error Code = 17,433
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:236)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:420)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801)
at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:297)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:221)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPhysicalConnection(OracleConnectionPoolDataSource.java:157)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:94)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:75)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper$1.run(InternalGenericDataStoreHelper.java:897)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper.getPooledConnection(InternalGenericDataStoreHelper.java:892)
at com.ibm.ws.rsadapter.spi.WSRdbDataSource.getPooledConnection(WSRdbDataSource.java:1181)
at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.createManagedConnection(WSManagedConnectionFactoryImpl.java:1047)
at com.ibm.ws.rsadapter.spi.WSDefaultConnectionManagerImpl.allocateConnection(WSDefaultConnectionManagerImpl.java:81)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:431)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:400)
In both cases I won't the exception if I pass the credentials to the getConnection method
Thanks for your advice.
Short answer: external clients don't get to use the authentication alias data
Longer Answer:
From the WAS J2C connection factory documentation:
The alias that you configure for component-managed authentication does not apply to all clients that must access the secured resource. External Java clients with Java Naming and Directory Interface (JNDI) access can look up a Java 2 Connector (J2C) resource such as a data source or Java Message Service (JMS) queue. However, they are not permitted to take advantage of the component-managed authentication alias defined on the resource. This alias is the default value that is used when the getConnection() method does not specify any authentication data, like user and password, or a value for ConnectionSpec. If an external client needs to get a connection, it must assume responsibility for the authentication by passing it through arguments on the getConnection() call.
It's been a long time since I've done anything with WebSFEAR^H^H^H^Hphere, but it looks to me that you have a configuration problem. There was a special screen where you'd create credentials (user/pass) and later you'd apply those credentials to the created data source. It looks like that your configured data source hasn't got credentials applied.
Even after defining the user/password values as custom properties I found that the connections for Oracle weren't working. After many days, I just found that the development server is running an old WAS 6.1 version, the problem I'm having was fixed in WAS 6.1.0.5: PK32838: J2CA0046E WHEN USING USING CUSTOM PROP PASSWORD ON DATASOURECE
I tried my code in a different WAS server with an updated WAS fix pack level and... it worked without introducing a single change in the code or in the configuration. So the solution is to upgrade the WAS server.
Thanks.

Categories

Resources