0

I currently have a web app that has certain classes able to connect to my database, but one other class cant.For whatever reason, I have started to get this exception for one of my classes. Here is what I have done:

  1. I am working with Java 7 and have ojdbc7 in both my class path and lib folder
  2. I have multiple classes who can connect to the url file, yet my other class cant and throws "java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:@someurl"
  3. My class is able to access the database AFTER I have connected to it in another class
  4. I have a config.properties file that contains the URL, so I know the URL is not at fault and never changes

Here is my code where the program fails. I don't connect to the database until I call this method too:

    public SimpleEntry<String, String> loadOrders(File file) {
    SimpleEntry<String, String> response = new SimpleEntry<String, String>(
            "", "");
    PreparedStatement st = null;
    ResultSet rs = null;
    Connection con = null;

    try {
        Scanner scan = new Scanner(file);
        String header = "";
        String trailer = "";
        int orderCtr = 0;
        int valueCtr = 0;
        String request = "";

        ArrayList<HashMap<String, String>> orders = 
new ArrayList<HashMap<String, String>>();

        log.info("Scanning content");
        // start to scan content
        while (scan.hasNextLine()) {
            String line = scan.nextLine();
            Scanner sc = new Scanner(line);
            sc.useDelimiter("\t");
            String type = sc.next();

            // differentiates between header, trailer, and content
            if (type.equals("H")) {
                header = line;
            } else if (type.equals("T")) {
                trailer = line;
                break;
            } else {
                // begin to enter in data appropriately from method's
                // parameter
                // key of map = column, value = data being inserted
                HashMap<String, String> order = new HashMap<String, String>();

                // Format:
                /*
                 * CLIENT_CUSTOMER_ID, FIRST_NAME, LAST_NAME,___, ADDRESS1,
                 * ADDRESS2, CITY, STATE, POSTAL_CODE, PHONE, EMAIL_ADDRESS,
                 * STORE_NUMBER, DELIVERY_METHOD,___, REWARD_VALUE,___,___,
                 * CARD_ACTIVE_DATE, CARD_EXPIRED_DATE, REQUEST
                 */

                order.put("CLIENT_CUSTOMER_ID", sc.next());
                String name = sc.next();
                order.put("FIRST_NAME", name.substring(0, 1).toUpperCase()
                        + name.substring(1).toLowerCase());
                name = sc.next();
                order.put("LAST_NAME", name.substring(0, 1).toUpperCase()
                        + name.substring(1).toLowerCase());
                sc.next();
                order.put("ADDRESS1", sc.next());
                order.put("ADDRESS2", sc.next());
                order.put("CITY", sc.next());
                order.put("STATE", sc.next());
                order.put("POSTAL_CODE", sc.next());
                order.put("PHONE", sc.next());
                order.put("EMAIL_ADDRESS", sc.next());
                order.put("STORE_NUMBER", sc.next());
                order.put("DELIVERY_METHOD", sc.next());
                sc.next();

                // purpose of valueCtr -> count reward values for a total
                String oVal = sc.next();
                valueCtr += Integer.parseInt(oVal);
                order.put("REWARD_VALUE", oVal);
                sc.next();
                sc.next();
                order.put("CARD_ACTIVE_DATE", sc.next());
                order.put("CARD_EXPIRED_DATE", sc.next());
                // used later in program
                request = sc.next();
                order.put("REQUEST", request);

                orders.add(order);

                // count number of orders
                orderCtr++;
            }
            sc.close();
        }
        scan.close();

        log.info("Scanning complete");

        // finds if the trailer contains the correct value and order amount
        boolean ok = true;
        if (!trailer.contains(Integer.toString(valueCtr))) {
            ok = false;
        }
        if (!trailer.contains(Integer.toString(orderCtr))) {
            ok = false;
        }

        // if the trailer doesnt, throw error
        if (!ok) {
            log.error("Error in loadOrders: Order Count
and/or total value of file \n does not match trailer amounts");
            response = new SimpleEntry<String, String>("ERROR",
                    "Order Count and/or total value of file \n does 
not match trailer amounts");
            return response;
        }

        String className = "oracle.jdbc.driver.OracleDriver";
        Class.forName(className);
        con = DriverManager.getConnection(Env.getCardUrl(),
                Env.getCardUser(), Env.getCardPass());

        log.info("Starting insertion statement");
        String query = "SELECT MAX(BATCH_ID) + 1 FROM INTEGRATION.OL_ORDER";
        st = con.prepareStatement(query);
        rs = st.executeQuery();

        rs.next();
        int batch = rs.getInt(1);

        String insert = "INSERT INTO INTEGRATION.OL_ORDER ("
                + "BATCH_ID, "
                + "CLIENT_CUSTOMER_ID, "
                + "FIRST_NAME, "
                + "LAST_NAME, "
                + "ADDRESS1, "
                + "ADDRESS2, "
                + "CITY, "
                + "STATE, "
                + "POSTAL_CODE, "
                + "PHONE, "
                + "EMAIL_ADDRESS, "
                + "STORE_NUMBER, "
                + "DELIVERY_METHOD, "
                + "REWARD_VALUE, "
                + "CARD_ACTIVE_DATE, "
                + "CARD_EXPIRED_DATE, "
                + "REQUEST,"
                + "PASSPHRASE, "
                + "ITEM_CODE, "
                + "CONFIRMED_MAILADDR, "
                + "JET_CLIENT_ID) VALUES(?, ?, ?, ?, ?, ?, ?, 
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

        st = con.prepareStatement(insert);

        log.info("Insertion complete, reorganizing data");
        // add batch
        for (HashMap<String, String> o : orders) {

            st.setInt(1, batch);

            // first, last, address1, address2, city, state, postal, phone,
            // storenum, delivery
            // validation and formatting
            ArrayList<String> content = validateContent(
                    o.get("FIRST_NAME"), o.get("LAST_NAME"),
                    o.get("ADDRESS1"), o.get("ADDRESS2"), o.get("CITY"),
                    o.get("STATE"), o.get("POSTAL_CODE"), o.get("PHONE"),
                    o.get("STORE_NUMBER"), o.get("DELIVERY_METHOD"));

            st.setString(2, o.get("CLIENT_CUSTOMER_ID"));
            st.setString(3, content.get(0));
            st.setString(4, content.get(1));
            st.setString(5, content.get(2));
            st.setString(6, content.get(3));
            st.setString(7, content.get(4));
            st.setString(8, content.get(5));
            st.setString(9, content.get(6));
            st.setString(10, content.get(7));
            st.setString(11, o.get("EMAIL_ADDRESS"));
            st.setString(12, content.get(8));
            st.setString(13, content.get(9));
            st.setInt(14, Integer.parseInt(o.get("REWARD_VALUE")));
            st.setDate(15, stringToDate(o.get("CARD_ACTIVE_DATE")));
            st.setDate(16, stringToDate(o.get("CARD_EXPIRED_DATE")));
            st.setString(17, o.get("REQUEST"));
            st.setString(18, getRandom());
            st.setString(19, "17331-000002");
            st.setString(20, "0");
            st.setInt(21, 97);

            st.addBatch();
        }

        st.executeBatch();

        log.info("Reorganization complete");
        response = new SimpleEntry<String, String>(Integer.toString(batch),
                request);

    } catch (Exception e) {
        StringWriter errors = new StringWriter();
        e.printStackTrace(new PrintWriter(errors));
        String temp = errors.toString();
        log.fatal("Error inside loadOrders(): " + temp);
        return null;
    } finally {
        Dir.close(rs, st, con);
    }

    return response;
}

My code for Dir.close:

public static void close(ResultSet rs, Statement ps, Connection conn) {

    Logger logger =LogManager.getLogger("AE");

    if (rs != null) {
        try {
            rs.close();

        } catch (SQLException e) {
            logger.error("The result set cannot be closed.", e);
        }
    }
    if (ps != null) {
        try {
            ps.close();
        } catch (SQLException e) {
            logger.error("The statement cannot be closed.", e);
        }
    }
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) {
            logger.error("The data source connection cannot be closed.", e);
        }
    }
}
antihero989
  • 486
  • 1
  • 10
  • 32
  • Can you clarify the location of your OJDBC JAR? Is it located within your WAR, or within the web server's lib directory? – Tim Jul 30 '14 at 19:06
  • 1
    Are you saying that your database connection code only works if you call `Class.forName("oracle.jdbc.driver.OracleDriver")`? If so, that sounds like expected behavior if you're using a JDBC driver before 4.0. See http://stackoverflow.com/questions/8053095/what-is-the-actual-use-of-class-fornameoracle-jdbc-driver-oracledriver-while. – Tim Jul 30 '14 at 19:11
  • @Tim Within the war, sorry. – antihero989 Jul 30 '14 at 19:17
  • @Tim no, that is not the issue. – antihero989 Jul 30 '14 at 19:19
  • What is the code that fails to load the driver for the URL? Can you post that code? (I understand based on your comments that `loadOrders()` succeeds in connecting, and some other code fails, so if that's not right, please clarify what code is succeeding and what code is failing, and post both.) – Tim Jul 30 '14 at 19:28
  • @Tim loadOrders is where it fails, specifically at the creation of my insert statement – antihero989 Jul 30 '14 at 19:57
  • It definitely sounds like your JAR isn't on the webapp's classpath. (Have you made sure that the JAR is in fact being packaged into the WAR and gets deployed to the web server?) One option would be to put the JAR in the web server's lib directory instead of the webapp's lib directory, which should ensure that it's available to all webapps. In theory, that shouldn't change anything, but if that works and you can move on, that might be worth trying. – Tim Jul 30 '14 at 20:08
  • Also, are you sure that it's the `con.prepareStatement()` call that throws the exception? My Google searching seemed to indicate that most people see that exception when calling `DriverManager.getConnection()`. – Tim Jul 30 '14 at 20:10
  • @Tim The JAR was on the webapp's class, apparently when deploying my WAR file, tomcat was referencing an older WAR file or something. After exporting my WAR file and renaming it followed by deploying it under that name, I was not getting the error anymore. Something else to think about what my messiness in the previous war file; I wasn't closing PreparedStatements, Results, and even the Connection variables correctly. Updating the war with a different name with the code posted above worked. – antihero989 Jul 31 '14 at 14:59

1 Answers1

0

As mentioned in my last comment, the JAR was on the webapp's class which meant the error couldn't be caused by a lack of drivers. Apparently when deploying my WAR file, tomcat was referencing an older WAR file or something with code that was not updated with the code I had posted above. After exporting my WAR file and renaming to an arbitrary name followed by deploying it under that name, I was not getting the error anymore. Something else to think about is the my messiness of code in the previous war file; I wasn't closing PreparedStatement, Result, and even the Connection variables correctly. Updating the war with a different name with the code posted above worked.

antihero989
  • 486
  • 1
  • 10
  • 32