Detect connection leaks in pooled DataSource - connection-pooling

I am writing code in order to detect whether my application is leaking connections or not. I use c3p0 as connection pool.
In my unit tests, I have tried to create a #Rule that checks, at the end of the tests, that there are no pending connections. This will help me find code that is forgetting to close Connections. For now, this has to work with c3p0 pool.
I have written the following code:
public class ConnectionLeakChecker extends Verifier
{
private DataSource dataSource;
#Override
protected void verify() throws Throwable
{
if (dataSource == null)
return;
if (dataSource instanceof PooledDataSource)
{
PooledDataSource pool = (PooledDataSource) dataSource;
int numBusyConnectionsDefaultUser = pool.getNumBusyConnectionsDefaultUser();
if (numBusyConnectionsDefaultUser > 0)
throw new AssertionError("Connections not released: " + numBusyConnectionsDefaultUser);
}
else
throw new AssertionError("Database pool type not supported: " + dataSource.getClass().getCanonicalName());
}
public DataSource getDataSource()
{
return dataSource;
}
public void setDataSource(DataSource dataSource)
{
this.dataSource = dataSource;
}
}
However, when instantiating the component as #Rule, it will randomly detect one pending connections (in my current tests, I use only one).
Some tests will have a connection hanging, others not. If I run a failing test alone, I usually don't get any more complaints.
I think the getNumBusyConnectionsDefaultUser() method does not do what I would like to achieve.
Somebody help?

Related

waitForConfirmsOrDie vs PublisherCallbackChannel.Listener

I need to achieve the impact of waitForConfirmsOrDie in core java implementation in spring . In core java it is achievable request wise ( channel.confirmSelect , set Mandatory , publish and Channel.waitForConfirmsOrDie(10000) will wait for 10 sec)
I implemented template.setConfirmCallback ( hope it is same as PublisherCallbackChannel.Listener) and it works great , but ack/nack is at a common place ( confirm call back ) , for the individual sender no idea like waitForConfirmsOrDie , where he is sure within this time ack hasn't came and can take action
do send methods wait for specified period internally like waitForConfirmsOrDie in spring if ack hasn't came and if publisherConfirms is enabled.
There is currently no equivalent of waitForConfirmsOrDie in the Spring API.
Using a connection factory with publisher confirms enabled calls confirmSelect() on its channels; together with a template confirm callback, you can achieve the same functionality by keeping a count of sends yourself and adding a method to your callback to wait - something like...
#Autowired
private RabbitTemplate template;
private void runDemo() throws Exception {
MyCallback confirmCallback = new MyCallback();
this.template.setConfirmCallback(confirmCallback);
this.template.setMandatory(true);
for (int i = 0; i < 10; i++) {
template.convertAndSend(queue().getName(), "foo");
}
confirmCallback.waitForConfirmsOrDie(10, 10_000);
System.out.println("All ack'd");
}
private static class MyCallback implements ConfirmCallback {
private final BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
#Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
queue.add(ack);
}
public void waitForConfirmsOrDie(int count, long timeout) throws Exception {
int remaining = count;
while (remaining-- > 0) {
Boolean ack = queue.poll(timeout, TimeUnit.MILLISECONDS);
if (ack == null) {
throw new TimeoutException("timed out waiting for acks");
}
else if (!ack) {
System.err.println("Received a nack");
}
}
}
}
One difference, though is the channel won't be force-closed.
Also, in a multi-threaded environment, you either need a dedicated template/callback per thread, or use CorrelationData to correlate the acks to the sends (e.g. put the thread id into the correlation data and use it in the callback).
I have opened AMQP-717 for us to consider providing something like this out of the box.

write Junit for JNDI

I used JNDI connection in my application and it is working. But I need to write Junits to test the connection. We dont use any spring framework. This is the method i wrote to get JNDI connection.
public Connection getConnection() throws SQLException {
DataSource ds = null;
InitialContext ic = null;
Connection con = null;
try {
ic = new InitialContext();
ds = (DataSource) ic.lookup("java:/DBs");
con = ds.getConnection();
return con;
} catch (Exception e) {
throw new SQLException(e);
}
}
You can make use of the SimpleNamingContextBuilder that comes with the spring-test library. You can use this even if you aren't using Spring as it isn't Spring specific.
Below is an example of setting up a JNDI connection in the #Before of the JUnit test.
package com.example;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
public class SomeTest
{
#Before
public void contextSetup () throws Exception
{
SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
DriverManagerDataSource dataSource = new DriverManagerDataSource("org.hsqldb.jdbcDriver", "jdbc:hsqldb:mem:testdb", "sa", "");
builder.bind("java:comp/env/jdbc/ds1", dataSource);
builder.bind("java:comp/env/jdbc/ds2", dataSource);
}
#Test
public void testSomething () throws Exception
{
/// test with JNDI
}
}
UPDATE: This solution also uses Spring's DriverManagerDataSource. If you want to use that you will also need the spring-jdbc library. But you don't have to use this, you can create any object you like and put it into the SimpleNamingContextBuilder. For example, a DBCP connection pool, a JavaMail Session, etc.
OK. After lot of searching i found a solution.And it is working for me. I want to share this to everybody. Hope this thing might help people who are having the same issue. Please add the below code.Add ojdb6.jar and naming-common-4.1.31.jar in your test libraries
#BeforeClass
public static void setUpClass() throws Exception {
try {
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES,"org.apache.naming");
InitialContext ic = new InitialContext();
ic.createSubcontext("java:");
ic.createSubcontext("java:/comp");
ic.createSubcontext("java:/comp/env");
ic.createSubcontext("java:/comp/env/jdbc");
OracleConnectionPoolDataSource ocpds = new OracleConnectionPoolDataSource();
ocpds.setURL("your URL");
ocpds.setUser("your username");
ocpds.setPassword("your password");
ic.bind("java:/yourJNDIName", ocpds);
} catch (NamingException ex) {
Logger.getLogger(yourTesTClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
If this is running outside the app server, then you'll likely need to supply parameters to the call for the InitialContext. But also realize that many DataSource implementations are not serializable so they won't work outside the container.
What you're writing is an integration test and it should be run in the container.

How to use InputStream and OutputStream on the Event thread

I am new to blackberry development and I am creating a native blackberry application. On every screen of my application, I need to send and receive data to the server on the same connection.
What I have done so far is I have made a ConnectToServer class which has a bunch of methods for sending and receiving. I instantiate it on the main screen and I pass it to each screen as a parameter.
That class in not a thread because I only read and write when the user types in information and presses a button. So basically I am using the inputStream and outputStream on the event thread which I hear is BAD. Then I ask ConnectToServer to get me what the server sent. For instance, I get a vector which I use to make a ListField.
How can I make these UI updates?
public class Screen3 extends MainScreen {
ConnectToServer con;
Vector v;
public Screen3(String exerciseName, ConnectToServer connect)
{
con = connect;
con.send(exerciseName);
v = con.receiveVector();
mylist = new listField();
mylist.setSize(v.size());
add(mylist);
}
public void drawListRow(...)
{
graphics.drawText((String) v.elementAt(index)
}
}
So, there's many ways to approach this. First of all, since it seems like you only want one instance of ConnectToServer, and you are currently having to pass that around, you might try making that class a Singleton object. This is not necessary, and does not have anything to do with your threading problem, but I only offer it as a solution, for situations where you want to enforce that there's only one instance of something, and want to avoid having to pass it around everywhere. A simple Singleton implementation might be this:
public class ConnectToServer {
private static ConnectToServer _instance;
/** use this static method to get the one and only instance */
public static ConnectToServer getInstance() {
if (_instance == null) {
_instance = new ConnectToServer();
}
return _instance;
}
/** private to enforce Singleton pattern */
private ConnectToServer() {
}
}
And use it in your screens like this (no need to pass it into the constructor any more):
ConnectoToServer connection = ConnectToServer.getInstance();
connection.blahBlahBlah();
Now, on to the threading problem. You're right that you should not be performing network requests on the main (aka "UI", aka "Event") thread. If you have a nice separate ConnectToServer class, that makes it easier to encapsulate this behaviour. Instead of UI clients using a synchronous send() and receiveVector() method, make one method that just kicks off the request, and another callback method that the ConnectToServer class will call when the response comes back. The ConnectToServer class will use a Thread to perform this work, and thus avoid freezing the UI during the request.
I'll define an interface that the UI clients will implement:
public interface RequestListener {
/** listeners must implement this method to get data. method will be called on the UI thread */
void onDataReceived(Vector response);
}
And then the new (partial) ConnectToServer class:
public class ConnectToServer {
private Thread _worker;
private RequestListener _listener;
public void setRequestListener(RequestListener listener) {
// note: this implementation only allows one listener at once.
// make it a list if you need something more
_listener = listener;
}
/** initiate a network request on a background thread */
public void sendRequest(final String request) {
_worker = new Thread(new Runnable() {
public void run() { // run on the background/worker thread
send(request);
final Vector response = receiveVector();
if (_listener != null) {
// this assumes all our listeners are UI objects, so we pass
// data back to them on the UI thread:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() { // run on UI thread
_listener.onDataReceived(response);
}
});
}
}
});
_worker.start();
}
}
Note that you should also make your original send() and receiveVector() methods in this class private. They should only be called from inside the class now, not directly from UI clients.
Then, you need to code your Screen classes like this:
public class Screen3 extends MainScreen implements RequestListener {
public Screen3(String exerciseName) {
ConnectToServer connection = ConnectToServer.getInstance();
connection.setRequestListener(this);
// kick off the request (on a background thread)
connection.sendRequest(exerciseName);
}
public void onDataReceived(Vector response) {
if (mylist == null) {
// first time data has been received, so create and add the list field:
mylist = new listField();
add(mylist);
}
mylist.setSize(response.size());
// TODO: presumably, you would copy the contents of 'response' into 'mylist' here
}
}
Also, you might also want to code the server class to protect against multiple UI clients making concurrent requests, allow current requests to be cancelled, etc. But the above should get you started on a solution that provides a responsive app, without freezing your UI.

Should I throw an EJBException to prevent Entity creation

I have the following code:
JSF Managed Bean:
#ManagedBean(name = "purchaseView")
#ViewScoped
public class PurchaseView implements Serializable {
#EJB
private PurchaseService service;
private Order order;
// Getter/Setters here
public void checkoutOrder() {
// .. some checks for null here, then call service
service.checkout(order);
}
}
Service:
#Stateless
public class BuyVoucherService {
#EJB
private OrderBean orderBean;
#EJB
private ProductBean productBean;
public boolean checkout(Order order) {
orderBean.create(order);
for(int i=0;i<order.getQuantity();i++) {
Product product = new Product();
if(someCondition) {
// don't save anything and
return false;
}
// .. some setter here
product.setOrder(order);
productBean.create(product);
}
return true;
}
The productBean and orderBean are simple JPA EJB with the EntityManager and CRUD operation (Generated by Netbeans..).
In the Service above, things are persisted in the database when the Service returns. In the case something is wrong (someCondition == TRUE above), if I return false the orderBean.save(order) will still persist the order in the database, and I don't want that.
Is throwing an EJBException and catching it in the ManagedBean the best option?
As you haven't specified any transaction attribute explicitly, it will be most probably Required, but depends on the server. Therefore both these methods will be within same transaction, so rolling back in a method will cascade the changes in another.
You can also try using Mandatory attribute for the 2nd method, it will ensure that it requires a transaction to proceed further, else will cause runtime exception.
#Resource
private EJBContext context;
try{
if(someCondition) {
throw SomeBusinessException("Failed, rolling back");
}
}catch(Exception e){
log(e.getMessage, e)
context.setRollbackOnly();
}
Else, you can throw system exception, that will force the container to rollback the changes being made.
if(someCondition)
throw SomeBusinessException("Failed, rolling back");
}catch(Exception e){
throw new EJBException (e.getMessage(), e);
}

jedis pubsub and timeouts: how to listen infinitely as subscriber?

I'm struggling with the concept of creating a Jedis-client which listens infinitely as a subscriber to a Redis pubsub channel and handles messages when they come in.
My problem is that after a while of inactivity the server stops responding silently. I think this is due to a timeout occurring on the Jedis-client I subscribe with.
Would this likely indeed be the case? If so, is there a way to configure this particular Jedis-client to not timeout? (While other Jedispools aren't affected with some globally set timeout)
Alternatively, is there another (best practice) way of what I'm trying to achieve?
This is my code, (modified/ stripped for display) :
executed during web-server startup:
new Thread(AkkaStarter2.getSingleton()).start();
AkkaStarter2.java
private Jedis sub;
private AkkaListener akkaListener;
public static AkkaStarter2 getSingleton(){
if(singleton==null){
singleton = new AkkaStarter2();
}
return singleton;
}
private AkkaStarter2(){
sub = new Jedis(REDISHOST, REDISPORT);
akkaListener = new AkkaListener();
}
public void run() {
//blocking
sub.psubscribe(akkaListener, AKKAPREFIX + "*");
}
class AkkaListener extends JedisPubSub {
....
public void onPMessage(String pattern, String akkaChannel,String jsonSer) {
...
}
}
Thanks.
ermmm, the below solves it all. Indeed it was a Jedis thing
private AkkaStarter2(){
//0 specifying no timeout.. Overlooked this 100 times
sub = new Jedis(REDISHOST, REDISPORT,0);
akkaListener = new AkkaListener();
}

Resources