Monthly Archives: July 2011

How Does OCI JDBC Application Communicate With Oracle Database Server

This post details out on what happens behind the scenes when an JDBC application using OCI driver communicates with the oracle database server.

A sample jdbc program looks like

import java.sql.*;
class DatabaseAccess{
  public static void main (String args []) throws Exception
  {
        Class.forName ("oracle.jdbc.OracleDriver");
        Connection conn = DriverManager.getConnection
             ("jdbc:oracle:oci:@hostname:1521:service_name", "scott", "tiger");

        ....
        ....
  }
}

As you can see, the program uses the JDBC OCI driver (a type 2 JDBC driver) to create a database connection. The Oracle JDBC OCI driver converts the JDBC invocations to calls to OCI (Oracle Call Interface) which are then sent over by Oracle Net to the Oracle database server. Read the rest of this entry

Advertisement

Java Proxies and UndeclaredThrowableException

A common approach in Java is to use dynamic proxies to provide decorator-style behavior. Doing this allows you to add additional behavior “around” an object without the object itself or it’s callers being aware of the decorating.

Let’s take an common implementation of java proxy.

public interface InterfaceA {
    void display() throws SQLException;
}

public class ClassA implements InterfaceA {

    @Override
    public void display() throws SQLException {
        throw new SQLException();
    }
}

public class ProxyHandler implements InvocationHandler {

    private InterfaceA delegate;

    public ProxyHandler(InterfaceA delegate) {
        this.delegate = delegate;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Inside the invocation handler");
        return method.invoke(delegate, args);
    }
}

public class ProxyApp {
    public static void main(String[] args) {
        createAndTestProxy();
    }

    private static void createAndTestProxy() {
        InterfaceA interfaceA = (InterfaceA) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                                                    new Class[]{InterfaceA.class}, new ProxyHandler(new ClassA()));
        try {
            interfaceA.display();
        } catch (java.sql.SQLException e) {
            throw new RuntimeException("Something bad happened", e);
        }
    }
}

If you run the ProxyApp class to test the proxy implementation, you would get the below exception trace

Inside the invocation handler
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
	at $Proxy0.display(Unknown Source)
	at proxy.ProxyApp.createAndTestProxy(ProxyApp.java:23)
	at proxy.ProxyApp.main(ProxyApp.java:16)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:110)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at proxy.ProxyHandler.invoke(ProxyHandler.java:26)
	... 8 more
Caused by: java.sql.SQLException
	at proxy.ClassA.display(ClassA.java:18)
	... 13 more

The expected stacktrace should have been

Inside the invocation handler
Exception in thread "main" java.lang.RuntimeException: Something bad happened
	at proxy.ProxyApp.createAndTestProxy(ProxyApp.java:25)
	at proxy.ProxyApp.main(ProxyApp.java:16)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:110)
Caused by: java.sql.SQLException
	at proxy.ClassA.display(ClassA.java:18)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at proxy.ProxyHandler.invoke(ProxyHandler.java:28)
	at $Proxy0.display(Unknown Source)
	at proxy.ProxyApp.createAndTestProxy(ProxyApp.java:23)
	... 6 more

Read the rest of this entry

Text Search In Jar Files

I found this  tool which can be help you to do a text search in jar files. Just execute the below command to start the application

java -jar Javinder.jar

Here is a sample snapshot

JDBC Driver Types & Architecture

The Data Access Handbook explains two major reasons a database driver can degrade the performance.

  1. The architecture of the driver is not optimal.
  2. The driver is not tunable. It does not have runtime performance tuning options that allow you to configure the driver for optimal performance. The type of options that we are talking about are ones that you can adjust to match your application and environment. For example, if your application retrieves large objects, look for a driver option that allows you to configure how much active memory the driver uses to cache a large object.

This post details on the different database driver architectures.

Four distinct architectures exist for database drivers: bridge, client-based, database wire protocol, and independent protocol. Choose a database driver that is implemented with an architecture that provides the best performance for your application.

Read the rest of this entry

Guava Immutable Collections vs Collections.unmodifiable

Java Collections

Collections.unmodifiableList or Collections.unmodifiableSet methods create a wrapper around the original list or set. Hence any changes to the original list would affect the unmodifiable list too.

Set<String> x = new HashSet<String>();
x.add("foo");
Set<String> builtIn = Collections.unmodifiableSet(x);
x.add("bar");
System.out.println(builtIn.size()); // Prints 2

It would be more clear if you have a look at the implementation of Collections.unmodifiableList() method

Read the rest of this entry