Monday, 20 July 2015

How to solve java.lang.UnsatisfiedLinkError: no ocijdbc11 in Java

"java.lang.unsatisfiedlinkerror no ocijdbc11 in java.library.path" error comes when you try to connect to Oracle 11g database using OCI (thick) driver by using tns name, but ocijdbc11.dll file is not available in PATH or java.library.path environment variable. ocijdbc11.dll is a native library and if you know Java searches native library in PATH or a location specified by java.library.path system property, if it doesn't find the dll, then it throws java.lang.unsatisfiedlinkerror no ocijdbc11 in java.library.path error. This dll is usually find in C:\Programs\Oracle\ora11g\bin\ocijdbc11.dll, but it could vary depending upon your Oracle installation. First step to solve this error is search for this dll in your machine, if you are using windows, just search in your C drive. If the dll is not there then you need to download that from Oracle's website. If its already present then just add its location into PATH variable. If you are explicitly providing java.library.path then also provide it there e.g.
-Djava.library.path=C:\Programs\Oracle\ora11g\bin\ocijdbc11.dll . By the way, if you truly wants to learn Java database programming from scratch, I suggest you to take a look at Practical database programming with Java book by Ying Bai. This book explains every important detail of Java database connectivity.


By the way this is not the standard way to connect to Oracle database from Java. Oracle users mainly use OCI driver for OS authentication or if they don't know the IP address of server and want to connect using TNSE, but if you are not concerned of that, you can always use Oracle JDBC thin driver to connect. For that you just need to include ojdbc.jar in your classpath. Just remember if you use an OCI URL e.g. "jdbc:oracle:oci:/@"+tnsName then you are using thick driver and you need oracle client libraries on the PATH, for that you need Oracle client to be installed in your machine, but if you use thin driver with following URL format "jdbc:oracle:thin:@"+dbServer+":"+port+":"+SID; you just need driver's JAR file and no native library will be required because its type 4 pure Java driver.


Error :

Exception in thread "main" java.lang.UnsatisfiedLinkError: no ocijdbc11 in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)


Analysis :

If you look at the error you will find that Java is complaining that ocijdbc11 dll is not found in java.library.path. If you further look then you will say that Oracle Driver is using System.loadLibrary() method to load native library, which explains why Java is searching for dll in java.library.path. BTW this is optional if you don't provide this system property Java will look on all folders included in PATH environment variable.


Solution:

There are two ways to solve the problem, first check if ocijdbc11.dll is present in your machine or not. For that do a wide search on your C driver where programs are installed. If you don't find this dll file then you need to install Oracle client to get this dll. If you install Oracle 11g in 64-bit Windows 7 machine then this native library can be found in C:\Programs\Oracle\ora11g\bin\ocijdbc11.dll folder. Now just add this folder in to your PATH and run your program again, provided any other error you should be able to connect to Oracle server.

Second solution is to use Oracle JDBC thin driver to connect Orace database. For this you need to change your JDBC URL format as "jdbc:oracle:thin:@"+dbServer+":"+port+":"+SID; and include ojdbc6.jar in to your CLASSPATH. Always remember difference between PATH and CLASSPATH, PATH is used to locate executable files, native library files but JAR is always loaded from classpath. This is also standard way to connect to Oracle 11g database.


java.lang.unsatisfiedlinkerror no ocijdbc11 in java.library.path in SQL Developer

After Toad, Oracle's SQL Developer is the next popular tool for connecting to Oracle database and this a Java client. That's why you need both thick and thin driver in your machine, which I guess also comes when you install SQL Developer. It uses thick driver when using TNS name and thin driver when using basic connection. For thick driver you need ocijdbc11.dll in your PATH and for thin driver you need ojdbc6.jar or ojdbc6_g.jar, later one is debug version. So if you get this error while using SQL Developer, follow the above step to sort it out.

If you are using Oracle 10g then you will likely to see java.lang.unsatisfiedlinkerror no ocijdbc10 in java.library.path, solution is same find the dll and add into PATH. Also ojdbc6.jar can be found in C:\Programs\Oracle\ora11g\jdbc\lib\ location, where ORACLE_HOME.

How to fix java.lang.unsatisfiedlinkerror no ocijdbc11 in java.library.path


Since this is also a type of java.lang.unsatisfiedlinkerror, you can also see this tutorial to get a general idea about how to solve this error in Java. You will likely to see this type of error whenever your Java program will use native libraries, either internal or external to do stuff.


That's all about how to fix java.lang.unsatisfiedlinkerror no ocijdbc11 in java.library.path error in Java. You get this error when you try to connect to an Oracle 11g database from Java program by using its TNS name and not the IP address. You can fix this error by adding ocijdbc11.dll in your PATH environment variable or into your java.library.path variable. If that DLL is not available in your system then download and install Oracle client like SQL Developer, which contains both thick and thin JDBC driver to connect to Oracle database. If you get java.lang.unsatisfiedlinkerror no ocijdbc10 in java.library.path it means you are connecting to Oracle 10g database but solution is same with only difference in Oracle version difference. Let us know if you face any issue while connecting to Oracle database from Java and I will try to help you here. 

Other common error which comes while connecting to database like Oracle, MySQL, SQL SERVER from Java program :
  • How to connect to MySQL database from Java Program [steps]
  • General Guide to solve java.lang.ClassNotFoundException in Java [guide]
  • java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory? [solution]
  • How to solve java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver in Java? [solution]
  • How to fix java.lang.ClassNotFoundException: org.postgresql.Driver error in Java? [solution]
  • How to solve java.lang.ClassNotFoundException:org.Springframework.Web.Context.ContextLoaderListener [solution]
  • How to solve java.lang.ClassNotFoundException: com.mysql.jdbc.Driver in Java MySQL? [solution]

How to use wait, notify and notifyAll in Java - Producer Consumer Example

You can use wait, notify and notifyAll methods to communicate between threads in Java. For example, if you have two threads running in your program e.g.Producer and Consumer then producer thread can communicate to consumer that it can start consuming now because there are items to consume in queue. Similarly a consumer thread can tell producer that it can also start putting items now because there is some space in queue, which is created as a result of consumption. A thread can use wait() method to pause and do nothing depending upon some condition. For example, in producer consumer problem, producer thread should wait if queue is full and consumer thread should wait if queue is empty. If some thread is waiting for some condition to become true, you can use notify and notifyAll methods to inform them that condition is now changed and they can wake up. Both notify() and notifyAll() method sends notification but notify sends notification to only one of the waiting thread, no guarantee which thread will receive notification and notifyAll() sends notification to all threads. So if only one thread is waiting on an object lock, also known as monitor then both notify and notifyAll wil send notification to it. If multiple threads are waiting on a monitor then notify will only inform one of the lucky thread and rest will not receive any notification, but notifyAll will inform all threads. In this Java multi-threading tutorial you will learn how to use wait, notify and notifyAll() method in Java to implement inter thread communication by solving producer consumer problem. BTW, if you are serious about mastering concurrency and multi-threading, I strongly suggest you to read Java Concurrency in Practice by Brian Goetz, without reading that book your journey to Java multi-threading is not complete. Its probably one of the most recommended book to Java developers.


How to use wait and notify in code

Even though wait and notify are quite a fundamental concept and they are defined in object class, surprisingly, its not easy to write code using wait and notify. You can test this during interview by asking candidate to write code to solve producer consumer problem using wait and notify by hand. I am sure many will stuck and make mistakes e.g. synchronizing at wrong place, not calling wait on right object or not following standard idiom. To be honest its confusing for non regular coders. First confusion arise from the fact, how to call wait() method? Since wait method is not defined in Thread class, you cannot simply call Thread.wait(), that won't work but since many Java developers are used to calling Thread.sleep() they try same thing with wait() method and stuck. You need to call wait() method on the object which is shared between two threads, in producer consumer problem its the queue which is shared between producer and consumer threads. Second confusion comes from the fact that wait needs to be call from synchronized block or method? So if you use synchronized block, which object should be put to go inside block? This should be the same object, whose lock you want to acquire i.e. the shared object between multiple threads. In our case its queue.

How to use wait and notify method in Java with example



Always call wait and notify from Loop Instead of If Block

Once you know that you need to call wait from synchronized context and on the shared object, next thing is to avoid mistake made by several Java developer by calling wait() method inside if block instead of while loop. Since you call wait inside a conditional block e.g. producer thread should call wait() if queue is full, first instinct goes towards using if block, but calling wait() inside if block can lead to subtle bugs because its possible for thread to wake up spuriously even when waiting condition is not changed. If you don't check the condition again after waking up by using loop, you will take wrong action which may cause problem e.g. trying to insert item on full queue or trying to consume from empty queue. That's why you should always call wait and notify method from loop and not from if block. I also suggest to read Effective Java item on same topic, probably the best reference in how to properly call wait and notify method.

Based upon above knowledge here is  the standard code template or idiom to call wait and notify method in Java :

// The standard idiom for calling the wait method in Java
synchronized (sharedObject) {
   while (condition) {
      sharedObject.wait(); // (Releases lock, and reacquires on wakeup)
   }
   ... // do action based upon condition e.g. take or put into queue
}

As I suggested, you should always invoke wait method from a loop. The loop is used to test the condition before and after waiting. If the condition still holds and the notify (or notifyAll) method has already been invoked before a thread calls wait() method, then there is no guarantee that the thread will ever awake from the wait, potentially causing a deadlock.



Java wait(), notify() and notifyAll() Example

Here is our sample program to demonstrate how to use wait and notify method in Java. In this program, we have used the standard idiom discussed above to call wait(), notify() and notifyAll() method in Java. In this program we have two threads named PRODUCER and CONSUMER and implemented using Producer and Consumer class which extends Thread class. The logic of what producer and consumer should do is written in their respective run() method. Main thread starts both producer and consumer threads and also create an object of LinkedList class to share as Queue between them. If you don't know LinkedList also implements Queue interface in Java. Producer runs in infinite loop and keep inserting random integer value into Queue until queue is full. We check this condition at while(queue.size == maxSize), remember before doing this check we synchronize on queue object so that no other thread modify the queue when we are doing this check. If Queue is full then our PRODUCER thread waits until CONSUMER thread consume one item and make space in your queue and call notify() method to inform PRODUCER thread. Both wait() and notify() method are called on shared object which is queue in our case.

import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;

/**
 * Simple Java program to demonstrate How to use wait, notify and notifyAll()
 * method in Java by solving producer consumer problem.
 * 
 * @author Javin Paul
 */
public class ProducerConsumerInJava {

    public static void main(String args[]) {
        System.out.println("How to use wait and notify method in Java");
        System.out.println("Solving Producer Consumper Problem");
        
        Queue<Integer> buffer = new LinkedList<>();
        int maxSize = 10;
        
        Thread producer = new Producer(buffer, maxSize, "PRODUCER");
        Thread consumer = new Consumer(buffer, maxSize, "CONSUMER");
        
        producer.start();
        consumer.start();
        

    }

}

/**
 * Producer Thread will keep producing values for Consumer
 * to consumer. It will use wait() method when Queue is full
 * and use notify() method to send notification to Consumer
 * Thread.
 * 
 * @author WINDOWS 8
 *
 */
class Producer extends Thread {
    private Queue<Integer> queue;
    private int maxSize;
    
    public Producer(Queue<Integer> queue, int maxSize, String name){
        super(name);
        this.queue = queue;
        this.maxSize = maxSize;
    }
    
    @Override
    public void run() {
        while (true) {
            synchronized (queue) {
                while (queue.size() == maxSize) {
                    try {
                        System.out .println("Queue is full, "
                                + "Producer thread waiting for "
                                + "consumer to take something from queue");
                        queue.wait();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }

                Random random = new Random();
                int i = random.nextInt();
                System.out.println("Producing value : " + i);
                queue.add(i);
                queue.notifyAll();
            }

        }
    }
}

/**
 * Consumer Thread will consumer values form shared queue.
 * It will also use wait() method to wait if queue is
 * empty. It will also use notify method to send 
 * notification to producer thread after consuming values
 * from queue.
 * 
 * @author WINDOWS 8
 *
 */
class Consumer extends Thread {
    private Queue<Integer> queue;
    private int maxSize;
    
    public Consumer(Queue<Integer> queue, int maxSize, String name){
        super(name);
        this.queue = queue;
        this.maxSize = maxSize;
    }
    
    @Override
    public void run() {
        while (true) {
            synchronized (queue) {
                while (queue.isEmpty()) {
                    System.out.println("Queue is empty,"
                            + "Consumer thread is waiting"
                            + " for producer thread to put something in queue");
                    try {
                        queue.wait();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                }
                System.out.println("Consuming value : " + queue.remove());
                queue.notifyAll();
            }

        }
    }
}

Output
How to use wait and notify method in Java
Solving Producer Consumper Problem
Queue is empty,Consumer thread is waiting for producer thread to put something in queue
Producing value : -1692411980
Producing value : 285310787
Producing value : -1045894970
Producing value : 2140997307
Producing value : 1379699468
Producing value : 912077154
Producing value : -1635438928
Producing value : -500696499
Producing value : -1985700664
Producing value : 961945684
Queue is full, Producer thread waiting for consumer to take something from queue
Consuming value : -1692411980
Consuming value : 285310787
Consuming value : -1045894970
Consuming value : 2140997307
Consuming value : 1379699468
Consuming value : 912077154
Consuming value : -1635438928
Consuming value : -500696499
Consuming value : -1985700664
Consuming value : 961945684
Queue is empty,Consumer thread is waiting for producer thread to put something in queue
Producing value : 1182138498

In order to understand this program better, I suggest you to debug it instead of running. Once you start your program in debug mode it will stop at either PRODUCER or CONSUMER thread, depending upon which one thread scheduler chose to give CPU. Since both threads has wait condition they will go there, now you just run it and see what it does, it will most likely print the output shown above. You can even use Step Into and Step Over buttons in Eclipse to run the program step by step to understand it better.



Things to Remember about Using wait(), notify() and notifyAll() method 


  1. You an use wait() and notify() method to implement inter thread communication in Java. Not just one or two threads but multiple thread can communicate to each other by using these methods.
  2. Always call wait(), notify() and notifyAll() methods from synchronized method or synchronized block otherwise JVM will throw IllegalMonitorStateException.
  3. Always call wait and notify method from loop and never from if() block, because loop test waiting condition before and after sleeping and handles notification even if waiting condition is not changed.
  4. Always call wait in shared object e.g. shared queue in this example.
  5. Prefer notifyAll() over notify() method due to reasons given in this article. 

Producer consumer solution in Java using wait and notify


That's all about how to use wait, notify and notifyAll() method in Java. You should use wait and notify for inter thread communication in Java only if you know what you are doing otherwise there are many high level concurrency utility available for different task. For example, if you want to implement producer consumer pattern then you can use BlockingQueue which will manage both thread-safety and flow control for you, if you want your thread should wait for other threads before proceeding you can use CycliBarrier or CountDownLatch or if you want to protect resource you can use Semaphore.