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
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
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.
- The architecture of the driver is not optimal.
- 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.
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