Our problem is as follows:
We have to connect to an ISeries with the JT400 and run some commands/Programs. The requirement is: Job is running in the QBatch with DISABLED user profile (because of security reasons).
We are able to make the JDBC connection, but getting the exception when executing the CommandCall/ProgramCall run() method. Our code is the following:
// This way we are able to create the JDBC connection without supplying a username/password
Class.forName("com.ibm.db2.jdbc.app.DB2Driver");
Connection connection = DriverManager.getConnection("jdbc:db2:*local;translate binary=true;prompt=false;naming=sql;libraries=MyLib");
// This way we are trying to connect to the Iseries and to execute CommandCall
AS400 as400 = new AS400();
CommandCall commandCall = new CommandCall(as400, "ADDLIBLE LIB(MyCmdLib)");
//Similarly executing ProgramCall as
ProgramCall programCall = new ProgramCall(as400, "/QSYS.LIB/OBJLIB.LIB/MYPGM.PGM", paramlist);
programCall.run();
and the exception is
com.ibm.as400.access.AS400SecurityException: User ID is
disabled.:NONACTUSR at
com.ibm.as400.access.AS400ImplRemote.returnSecurityException(AS400ImplRemote.java:2889)
at com.ibm.as400.access.CurrentUser.getUserInfo(CurrentUser.java:87)
at
com.ibm.as400.access.AS400ImplRemote.getPassword(AS400ImplRemote.java:1585)
at
com.ibm.as400.access.AS400ImplRemote.signon(AS400ImplRemote.java:3188)
at com.ibm.as400.access.AS400.sendSignonRequest(AS400.java:3465) at
com.ibm.as400.access.AS400.promptSignon(AS400.java:3043) at
com.ibm.as400.access.AS400.signon(AS400.java:4375) at
com.ibm.as400.access.CommandCall.chooseImpl(CommandCall.java:279) at
com.ibm.as400.access.CommandCall.run(CommandCall.java:713)
We searched on the internet but couldn´t find anyone with the same problem.
Thank you for reading our question.
You can't connect to the server with a disabled user.
Period. No exceptions.
It'd be a very insecure server if that was allowed.
You can create a User ID with password but set the Initial menu to *SIGNOFF for security reasons.
https://www.ibm.com/docs/en/i/7.2?topic=fields-initial-menu
Related
Dear StackOverFlowers,
I was trying event-driven LISTENER/NOTIFY on Postgres 9.6 (Windows 10).
I followed PGJDBC example given by Steve Taylor at https://www.openmakesoftware.com/postgresql-listen-notify-events-example/.
I started by downloading pgjdbc-ng-0.7-complete.jar and have put that in my CLASSPATH replacing standard JDBC driver.
When I am trying to connect to Postgres database using pgjdbc driver, I am getting an error:
connection received: host=127.0.0.1 port=50325
connection authorized: user=postgres database=scott
could not receive data from client: An existing connection was forcibly closed by the remote host.
Here are my system variables:
DBHost: localhost
DBName: scott
DBPort: 5432
DBUserName: postgres
DBPassword: postgres
I am not getting past the first hurdle, rest looks like Mount Everest. Please help me. Should you be needing the code, I am following Steve's code ditto.
Further to Joseph Larson's answer, the database is always running. I have connected to Postgres database from PGADMIN and Java successfully. I think issue is with the connect string. From Java when I am using standard JDBC which is provided by Postgres I am using URL like jdbc:postgresql://localhost:5432/dbname but PGJDBC suggests a different connect string like JDBC:PGSQL://localhost:5432/dbname. I tried to connect with that string (forcibly), it did not work. There is no method in PGJDBC PGDataSource for providing URL directly. I had to go through:
dataSource.setHost(DBHost);
dataSource.setPort(5432);
dataSource.setDatabase(DBName);
dataSource.setUser(DBUserName);
dataSource.setPassword(DBPassword);
And what URL it is sending to Database I am not able to figure out. Please suggest me a connect string and this problem is solved.
thanks
Thanks very much for asking me to post error messages:
Exception in thread "main" java.lang.NullPointerException
at com.impossibl.postgres.system.BasicContext.loadLocale(BasicContext.java:294)
at com.impossibl.postgres.system.BasicContext.init(BasicContext.java:273)
at com.impossibl.postgres.jdbc.PGConnectionImpl.init(PGConnectionImpl.java:251)
at com.impossibl.postgres.jdbc.ConnectionUtil.createConnection(ConnectionUtil.java:182)
at com.impossibl.postgres.jdbc.AbstractDataSource.createConnection(AbstractDataSource.java:723)
at com.impossibl.postgres.jdbc.PGDataSource.getConnection(PGDataSource.java:66)
at com.impossibl.postgres.jdbc.PGDataSource.getConnection(PGDataSource.java:58)
at PGListenNotify.<init>(PGListenNotify.java:26)
at PGListenNotify.main(PGListenNotify.java:37)
Here is source code:
import java.sql.SQLException;
import java.sql.Statement;
import com.impossibl.postgres.api.jdbc.PGConnection;
import com.impossibl.postgres.jdbc.PGDataSource;
public class PGListenNotify
{
PGConnection connection;
public PGListenNotify()
{
String DBHost = System.getenv("DBHost");
String DBName = System.getenv("DBName");
String DBUserName = System.getenv("DBUserName");
String DBPassword = System.getenv("DBPassword");
try
{
PGDataSource dataSource = new PGDataSource();
dataSource.setHost(DBHost);
dataSource.setPort(5432);
dataSource.setDatabase(DBName);
dataSource.setUser(DBUserName);
dataSource.setPassword(DBPassword);
connection = (PGConnection) dataSource.getConnection();
Statement statement = connection.createStatement();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
PGListenNotify ln = new PGListenNotify();
}
}
This looks like the Windows locale bug in pgjbdc-ng. It has been addressed, try the latest version 0.8.1.
The latest releases have detailed documentation related to asynchronous notifications here.
If it still fails to execute on your Windows system, please create an issue here.
Did you actually start a database server? I didn't know PostgreSQL server could run on Windows, but I've never tried.
I would simplify your problem a little. I know nothing about psql on Windows, but on Mac, I would start the server and then use the psql command (it's part of PostgreSQL) to ensure the server was up and running.
If you're to connecting, then the problems can be:
-There is no server at all
-The server isn't running on the port you're attempting
-The server isn't listening for connections on host 127.0.0.1 but could be listening on the actual IP address of your machine
-I'm not sure about that particular error, but username, password, or database may not exist.
I'd use psql to figure out which of those possible reasons is the real problem. That isolates out your program as being part of the problem, and it becomes entirely one of managing your database server.
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 have been trying to connect to Teradata
Class.forName("com.teradata.jdbc.TeraDriver");
String connectionString = "jdbc:teradata://xxx.xxxxxx.com/database=xxxxxx, tmode=ANSI, charset=UTF8";
String user = "Rocket512";
String password = "aui8mn5";
Connection conn = DriverManager.getConnection(connectionString, user, password);
Got the following
Exception in thread "main" com.teradata.jdbc.jdbc_4.util.JDBCException: [Teradata Database]
[TeraJDBC 14.10.00.17] [Error 8017] [SQLState 28000] The UserId, Password or Account is invalid.
at com.teradata.jdbc.jdbc_4.util.ErrorFactory.makeDatabaseSQLException(ErrorFactory.java:300)
at com.teradata.jdbc.jdbc.GenericLogonController.run(GenericLogonController.java:666)
at com.teradata.jdbc.jdbc_4.TDSession.<init>(TDSession.java:216)
I know that the host is specified correctly since i did not get UnknownHost Exception.
Also I have double checked my userid and password are correct.
I ran query suggested by #beni23 (thank you)
select *
from dbc.logonoff
where logdate >= date '2013-10-31'
Here is the result that I got
What is Bad Password? I used SQL Assistant with this very password and it works great. Why cannot i connect with Java?
LDAP Authentication failures will not be captured in DBC.LogOnOff as a Bad Password event because the authentication doesn't take place on the database.
Typically the error message you are receiving, The UserId, Password or Account is invalid., is indicative of the user account being locked on the database.
SELECT U.UserName
, U.ProfileName
, U.DefaultAccount
, COALESCE(P.MAXLOGONATTEMPTS, S.MAXLOGONATTEMPTS) AS MaxLogonAttempts_
, U.LockedCount
, U.LockedDate
FROM dbc.UsersV U
LEFT JOIN
dbc.ProfileInfoV P
ON P.ProfileName = U.ProfileName
CROSS JOIN
dbc.SecurityDefaults S
WHERE UserName = 'Rocket512';
If LockedCount is not 0 than a failed logon attempt has occurred since the last successful logon to the database.
If LockedDate is not NULL it represents the date which the account was last locked.
MaxLogonAttempts_ will tell you how many times you can attempt to logon using database authentication (TD2) before the account is locked.
A couple of things I would suggest:
Remove whitespace between the parameters of connectString
Put the User and Password parameters in the connectString
Using original code above modify the connectString to add: ,ACCOUNT=$AMRWRW&DrT&r which should match what is returned by the query in my response above (I have added DefaultAccount).
EDIT: 11/12/13
May I suggest you download Teradata Studio Express and attempt to make a connection to the same Teradata system using JDBC much like you are here in your code. This may help shed light on the parameters you need to specify in your connection string in order to make the connection successful. You should be able to setup your connection parameters in Teradata Studio Express the same as you have here in your code and see if it works.
Using LDAP as the logon mechanism for a user that has not been granted the explicit right to logon with a NULL password has resulted in the error message `The UserId, Password or Account is invalid.'. I received this the other day using a privileged account without changing my logon mechanism from LDAP to TD2.
What does the following SQL return?
SELECT *
FROM DBC.LogonRulesV
WHERE UserName = 'Rocket512';
It may not return anything, which is okay. This simply means you ability to logon with that userid from any host on the system has not been explicitly granted or revoked.
EDIT: 05/22/18
The “Bad Password” event for an externally authenticated user may will appear in the event log when the provided password and the what is stored on the directory server do not match. In certain scenarios you can verify this by using ldapsearch from the PDN to submit an inquiry directly to the LDAP directory. You can find more details about using this command in the Security Administration manual. I’ve discovered this trying to triage a problem with a subset of user accounts that fail to authenticate to the directory. I felt it would be appropriate to update this answer with more details as my lead in statement at the top is not 100% accurate.
The following might not give you a solution, but might point you in the right direction. I think you'll want to check the dbc.logonoff table in teradata through a console to make sure that your user is not locked or get an idea whether your driver is hitting teradata.
select *
from dbc.logonoff
where logdate >= date '2013-10-31'
Reading this article Troubleshooting Security: The UserId, Password or Account is invalid. we can see the typical reason of this error.
Cause: LOGMECH=LDAP is specified, and the username/password credentials
are redundantly provided in the both LOGDATA and as separate
connection parameters.
Solution: Identify LDAP users via LOGDATA, or
via separate username/password parameters, but not both
simultaneously.
So, you should check this case. May be you can get connection without user/password
Perhaps you might have more luck with:
String driver = "com.teradata.jdbc.TeraDriver";
String conUrl="jdbc:teradata://xxx.xxxxxx.com/database=xxxxxx,USER=Rocket512,PASSWORD=aui8mn5,tmode=ANSI,charset=UTF8";
Class.forName(driver);
Connection dbConn = DriverManager.getConnection(conUrl);
If that doesn't work make sure to use the latest jdbc driver.
I had similar error and followed all the suggestions given in here. My account was not locked and I was able to connect to the DB with the same username and password, via SQL assistance editor.
The solution worked for me was adding following line in the connection string: LOGMECH=LDAP.
You need to know the logon mechanism for your Teradata, or you can reach out to your DBA team, as I did. So your connection string will look something like this:
String connurl="jdbc:teradata://xx/database=xx,USER=xx,PASSWORD=xx,tmode=ANSI,charset=UTF8,LOGMECH=LDAP";
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.
I'm writing a desktop java app on that I want to connect to a MySQL database on a server. Here is the code to do that:
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
private static Connection getDBConnection() throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException {
String username = "myUserName";
String password = "myPassWord";
String url = "jdbc:mysql://www.domainName.com:3306/databaseName";
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting to database...");
//hangs here
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
When I run this, it hangs on the DriverManager.getConnection() call. Why does this happen? Is my URL malformed?
(I'm not getting any error messages, but the program doesn't respond as if in an infinite loop. I haven't waited longer than 90 seconds to see if the connection will ever be established.)
Also, what is the purpose of the Class.forName() call? How does it work?
I am almost entirely certain that the username and password are correct. (I just used userName and passWord as placeholders above.)
UPDATE: I fixed the port number, and now I get this error:
Cannot connect to database: java.sql.SQLException: Access denied
for user 'userName'#'r236059121.resnet.mySchool.edu' (using
password: YES)
Does this mean I need to configure settings on the database? Or does it mean that I've got the credentials wrong? (They work for PHP scripts deployed on the server that contains the database.)
SOLUTION: Added the host above to the Access Host list on cPanel.
Seems to me like your database is not reachable and you will probably get an error when the call runs into a timeout. Are you sure the hostname and port are right and reachable from your machine?
You don't need the newInstance() at the end of Class.forName(). Class.forName() triggers the classloader to load that class, which in turn triggers some internal registration code in the driver which makes the driver available.
I think the line should just be
Class.forName("com.mysql.jdbc.Driver");
(close the .newInstance() bit)
That causes the driver to register itself with the driver manager and allows the driver manager to pick a driver for the database url.
I think the hang is caused by a DNS problem, or some other reason why your db cannot be reached. By default, the MySQL JDBC driver does not time out for a connection. See http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html and look for connectTimeout.
In your code, you have
String url = "jdbc:mysql://www.domainName.com:portNumber/databaseName";
I take it that you used a real port there? By default, it should be 3306. You can test with the test database which is present in virtually all mysql instances:
String url = "jdbc:mysql://www.domainName.com:3306/test";
You also wrote:
String username = "myUserName";
String password = "myPassWord";
Obviously you should use real credentials here too. Ask your dba what they are. If you're the DBA then...well you should probably read up on MySQl administration :) Seriously when you installed MySQL you were probably promted for a password for the root user. Use those (in the obvious way)
In real code you should probably not hang when the db is not there. So I advise adding a connectTimeout option like so:
String url = "jdbc:mysql://www.domainName.com:3306/test?connectTimeout=3000";
(connectTimeout is in milliseconds, so this would time out after 3 seconds)
Rosarch - You are not able to connect to your DB since its unreachable.
It'll timeout after a while.
Try telnetting -
telnet <IP-OF-domainName.com> <PortNumber>
You'll mostly see that it shows timeout.
Solutions -
1.) If you are behind a firewall, you need to punch a hole to allow access
2.) If you are behind a proxy, need to configure it to allow access