I'm trying the use reflection to invoke a method that has a java.sql.Connection as argument.
public void setAndValidateSessionUUID(java.lang.String, java.sql.Connection);
I am on a Websphere 7 context using a jndi path to retrieve the data source and it's connection.
private java.sql.Connection connection;
Context ctx = new InitialContext();
DataSource dataSource = (DataSource) ctx.lookup(this.DataSourceJNDIPath);
this.connection = dataSource.getConnection();
I have the following piece of code to retrieve the method using reflection
public static Method getMethod(Class<?> clazz, String methodName, Class<?>... args) throws SecurityException, NoSuchMethodException {
return clazz.getMethod(methodName, args);
}
But when I try to retrieve the method it gives me the following error:
java.lang.NoSuchMethodException: setAndValidateSessionUUID(java.lang.String, com.ibm.ws.rsadapter.jdbc.WSJdbcConnection)
I have no problem executing the method without reflection but using it I can't retrieve the method.
Any ideas?
The server returns proxy objects, which you can observe via dataSource.getClass(). On WAS 8.0 and later, you can use the java.sql.Wrapper APIs to call vendor-specific APIs, but on WAS 7.0 and later, you'll need to use WSCallHelper.jdbcCall.
Yes. You may want to read my blog post here but basically, you need to iterate all of the classes methods for (Method method : cls.getMethods()) until you find one where each (and every) method parameter isAssignableFrom your input parameters...
if (!mTypes[i].isAssignableFrom(parameters[i]
.getClass()))
If it is, store it with toInvoke = method. Then use
toInvoke.invoke(receiver, parameters);
Related
I came across some JMS calling code that initializes the JMS session inside of its constructor. The calling code implements the ExceptionListener interface and passes a reference to this to the connection factory object, as shown below:
public class JmsCode implements ExceptionListener {
private static final Logger logger = LoggerFactory.getLogger(JmsCode.class);
public JmsCode(String url, String username, String password, String trustStorePath, char[] trustStorePassword) throws JMSException {
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
connectionFactory.setUserName(username);
connectionFactory.setPassword(password);
connectionFactory.setTrustStore(trustStorePath);
connectionFactory.setTrustStorePassword(new String(trustStorePassword));
connectionFactory.setExceptionListener(this);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
#Override
public void onException(JMSException e) {
logger.error("Unexpected JMS exception caught", e);
}
}
I am wondering if it is safe to pass a reference to this from the JmsCode constructor given that the object hasn't been fully constructed yet. I came across a similar question which had me reading up on IBM's article on not publishing this during construction. While I agree with their reasoning, I am not sure if it applies in this case since the only thing the exception listener is doing is logging via a static and final member. Is the code above safe (ignoring someone else being tempted to change the exception listener method to use some instance state of the object)?
This is in fact unsafe publishing, and it's theoretically possible for another object to see this one in an inconsistent state.
That said, while this isn't a good pattern (and it's just shown here to demonstrate ExceptionListener), the logic of the constructor shows that the class is in fact fully constructed by the time that the this reference escapes (because it has nothing to construct), and so in this exact case there's nothing that can go wrong.
Whether it is safe or not depends on where that reference to this can escape to. If, as a consequence of this call, this could be read by another thread, then it is not safe.
If you want to ensure an instance is completely initialized for safe publication and you want to publish it, a constructor isn't the right place to publish it. Instead, you'll need to create a Factory object or a static factory method which can construct the object safely and then publish it before returning it to the caller.
It is completely safe. You are just passing the this reference, not using anything in the this scope.
Something will go wrong on that iff the .setExceptionListener(this) method performs something else than being a setter.
I'm trying to increase my test coverage so I'm wondering, how would you go about testing for DataAccessExceptions being thrown in a DAO, for example in a simple findAll method which just returns all the data from your data source? In my case, I'm using Spring JdbcTemplates.
For general testing I have my setUp-method with an #Before annotation, mocking the jdbcTemplate used, setting it up in the DAO and mocking all jdbc calls. Now forcing a DataAccessException for something like a create method is pretty simple, just throw the exception when calling a create statement with the right primary keys.
However, I really have no idea how to handle this for methods like simple findAll methods which don't take any input parameters. Testing the valid implementation is straight forward, but how would you go about mocking having no DB connection without it affecting every other test or method?
This would be a concrete implementation of a method I'd like to test:
public List<SomeObject> findAll() throws PersistenceException {
final String sql = "SELECT * FROM SomeObject";
try {
return jdbcTemplate.query(sql, new JdbcSomeObjectMapper());
} catch (DataAccessException ex) {
LOG.error(ex.getMessage());
throw new PersistenceException(ex.getMessage());
}
}
Which would just return all objects in the data source. Testing for a valid call is easy since I can just mock the jdbcTemplate.query call, but I'd never enter the catch block unless there's a connection failure while retrieving the data, and that's what I'd like to test.
Using Mockito you can mock a Class and the method calls of that particular Class. A mocked object can also be asked to throw an exception when particular methods are called on it. First you have to mock your jdbcTemplate, then stub your exception
//mocking JdbcTemplate
JdbcTemplate template = Mockito.mock(JdbcTemplate.class);
Mockito.when(template.query(Mockito.anyString(), (RowMapper<YourClass>) Mockito.any(RowMapper.class))).thenThrow(EmptyResultDataAccessException.class);
//or using EasyMock
EasyMock.expect(template.query(Mockito.anyString(), (RowMapper<YourClass>) Mockito.any(RowMapper.class))).andThrow(new (typeofExecption));
DAOClass.makeDBConnection() method returns datasource configured (using lookup) in Application Server (Jboss). Need to implement junit test case for this scenario.
Using Mockito, tested the DAO method as follows. As it's not able to find the datasource(as expected), it's returning NullPointerException. How to handle NullPointerException and return the connection which i am creating in below code? OR is there any other better unit test framework which handles this scenario ?
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection("jdbc:sqlserver://DB:1433;DatabaseName=databasename", "userid", "password");
when(DAOClass.makeDBConnection()).thenReturn(conn);
Mockito can't mock static method calls the way you have it; it effectively works by dynamically overriding all methods via a generated subclass (proxy).
You will need to write a wrapper class around static methods that you want to mock, otherwise refactor the code to avoid the static call, or use a tool such as PowerMock to rewrite your system's bytecode at runtime.
I am trying to downcast java.sql.Connection to org.postgresql.jdbc4.Jdbc4Connection like this:
As you can see, Netbeans tells me localConn is ($Proxy6) org.postgresql.jdbc4.Jdbc4Connection#5894585b, and it is not an instance of org.postgresql.jdbc4.Jdbc4Connection.
So here are my questions:
What does ($Proxy6) org.postgresql.jdbc4.Jdbc4Connection#5894585b mean?
How can I get org.postgresql.jdbc4.Jdbc4Connection from it?
Thanks,
Update Information:
localConn instanceof org.postgresql.jdbc4.Jdbc4Connection returns false.
update
I use Mybatis.
I suppose that you are using iBatis/MyBatis. If so, there is a static method on com.ibatis.common.jdbc.SimpleDataSource that returns the unwrapped connection:
public static Connection unwrapConnection(Connection conn)
This method will return the real connection without the proxy, and you will can do the downcast.
A Proxy class is a class that wraps an existing Interface and lets you intercept calls
made to the object.
This causes a problem in that the proxy will only recognise that it is of that interface
type. Which in this case is most likely to be javax.sql.Connection.
you could try this
Connection conn = localConn.createStatement().getConnection();
I'm looking for a way to get the password from a java.sql.Connection object. I know there's a getUserName() method in the DatabaseMetaData object, but unfortunately no corresponding getPassword() method. Using the debugger in Netbeans I can see a field for the password, so there must be a way to get this information using reflection, but thus far I've been unable to figure out how.
As I commented, the only way must be looking into the code. For instance, for MySQL using the latest driver (5.1.15). You can get the password like this:
public static void main(String[] args) throws Exception{
ConnectionImpl con = (ConnectionImpl) DriverManager.getConnection("jdbc:mysql://localhost:3908/mydb?user=edalorzo&password=mandrake");
System.out.println(con.getProperties().get("password"));
con.close();
}
But for this, you would need to know the class hierarchy and its implementation details.
Other databases most probably will be different. If your database is open source, like MySQL you can know the details of the inner construction and find ways to retrieve the password.
It is up to the implementer of the JDBC to provide that since the user and password are being passed in as a Map to the Driver.
One way to know what the Password is, is to extend the driver and include that.
class CustomDriver extends ImplementerDriver {
#Override
public Connection connect(String url, Properties info) throws SQLException {
super.connect(url, info);
// Extract password from info.
}
public String getPassword() {
....
}
}
You can parse the sever XML configuration file for the Connection Pool parameters, and get the password from there. sophisticated solution but it works.