13

I wrote following the java program

import java.io.*;
import java.util.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.*;

public class Sample {
    public static void main (String[] args) throws IOException  {
                    int CountComputers;
            FileInputStream fstream = new FileInputStream(
                    "/export/hadoop-1.0.1/bin/countcomputers.txt");
            BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
            String result=br.readLine();
            CountComputers=Integer.parseInt(result);
            input.close();
            fstream.close();
            Connection con = null;
            Statement st = null;
                ResultSet rs = null;    
               String url = "jdbc:postgresql://192.168.1.8:5432/NexentaSearch";
                String user = "postgres";
                String password = "valter89";
            ArrayList<String> paths = new ArrayList<String>();
            try
            {
                con = DriverManager.getConnection(url, user, password);
                        st = con.createStatement();
                        rs = st.executeQuery("select path from tasks order by id");
                while (rs.next()) { paths.add(rs.getString(1)); };
                PrintWriter zzz = null;
                    try
                    {
                            zzz = new PrintWriter(new FileOutputStream("/export/hadoop-1.0.1/bin/readwaysfromdatabase.txt"));
                    }
                    catch(FileNotFoundException e)
                    {
                            System.out.println("Error");
                            System.exit(0);
                    }
                    for (int i=0; i<paths.size(); i++)
                {
                    zzz.println("paths[i]=" + paths.get(i) + "\n");
                    }
                    zzz.close();

            }
            catch (SQLException e) 
            {
                System.out.println("Connection Failed! Check output console");
                e.printStackTrace();
            }
        }
}

I compiled this program and created the jar file

./javac -classpath /folder/postgresql-8.4-703.jdbc3.jar -d /Samplejavaprogram/classes /Samplejavaprogram/src/Sample.java
./jar -cvf /Samplejavaprogram/Sample.jar -C /Samplejavaprogram/classes/ .

Jar has the following manifest file

Manifest-Version: 1.0
Created-By: 1.7.0_06 (Oracle Corporation)
Main-Class: Sample
Class-Path: /folder/postgresql-8.4-703.jdbc3.jar

also contains file /folder/postgresql-8.4-703.jdbc3.jar. I launched Sample.jar by means of a command

./java -jar -Djava.library.path=/opt/jdk1.7.0_06/lib /Samplejavaprogram/Sample.jar

and as a result I received the following messages

Connection Failed! Check output console
java.sql.SQLException: No suitable driver found for jdbc:postgresql://192.168.1.8:5432/NexentaSearch
    at java.sql.DriverManager.getConnection(DriverManager.java:604)
    at java.sql.DriverManager.getConnection(DriverManager.java:221)
    at org.myorg.Sample.main(Sample.java:33)

I launched the file from a host with the address 192.168.1.10, and on a host 192.168.1.8 it fulfilled normally. Help to eliminate an error.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
user2328488
  • 345
  • 2
  • 5
  • 9

3 Answers3

19

You are using a JDBC 3 driver. JDBC 4 drivers are loaded automatically loaded by the DriverManager whereas JDBC 3 drivers are not. Therefore you need to invoke

Class.forName("org.postgresql.Driver");

once in your application, (prior to invoking DriverManager#getConnection).


Alternatively, you can use the JDBC 4 PostgreSQL driver from here which will not require the above method call.

Reimeus
  • 158,255
  • 15
  • 216
  • 276
0

Just use the jar command to extract the files your application needs to make the connection with the database server. e.g. jar -xf jdbc_file. Compile it with the javac -cp . and run it with the java -cp .

And that's it. It will work.

0

Use DriverManager.registerDriver(new org.postgresql.Driver());

pedram bashiri
  • 1,286
  • 15
  • 21
  • The `DriverManager.registerDriver` method should normally only be called by JDBC drivers (they do so when the class is loaded). Application code should not call it (there are exceptions to this 'rule', but those are extremely rare) – Mark Rotteveel Oct 07 '19 at 09:26
  • @MarkRotteveel Thanks for the comment. But you can't just say something shouldn't be used without providing any reason or details. At least a link to where this is documented would be helpful. – pedram bashiri Oct 08 '19 at 18:29
  • Quote from the javadoc of [`DriverManager.registerDriver`](https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/DriverManager.html#registerDriver(java.sql.Driver)): _" A newly-loaded driver class should call the method registerDriver to make itself known to the DriverManager."_ which implies that it should normally be called by `Driver` implementations. And [`java.sql.Driver`](https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/Driver.html): _"When a Driver class is loaded, it should create an instance of itself and register it with the DriverManager."_ – Mark Rotteveel Oct 08 '19 at 18:43
  • I'd also suggest to read the [JDBC 4.3 Specification](https://jcp.org/en/jsr/detail?id=221), section 9.2 which describes how drivers register themselves and how drivers are loaded. All this makes clear that the method isn't intended for user code to call. – Mark Rotteveel Oct 08 '19 at 18:48
  • Thanks, that helped. The reason I suggested this solution is, from what I remember, "Class.forName(something)" didn't work for me, and after some googling I found "https://docs.oracle.com/cd/F49540_01/DOC/java.815/a64685/basic1.htm" which is very old but I gave it a try anyway and it worked. But now, going through the links you posted I agree, this should not be used. – pedram bashiri Oct 08 '19 at 22:22
  • 1
    What that Oracle documentation describes will work, but it is not how a JDBC driver is intended to be used. They probably documented because of the note about `Class.forName`. _"However, this method is valid only for JDK-compliant Java virtual machines. It is not valid for Microsoft Java virtual machines."_, which seems to date this to around the end of the '90s, start of the 2000s when Microsoft had their own, not always compatible, variant of Java. – Mark Rotteveel Oct 09 '19 at 09:00