markbratanov
markbratanov

Reputation: 898

Unhandled exception Class.forname("com.google.cloud.sql.jdbc.Driver") in Android Studio

I have a project in Android Studio that has a Google Cloud Endpoints module. I'm trying to connect my endpoints module to an instance of Google Cloud SQL that I have in that same project.

In the IDE I see the following error:

Unhandled exception: java.lang.ClassNotFoundException

My gradle build shows:

Error:(82, 26) error: unreported exception ClassNotFoundException; must be caught or declared to be thrown 
Error:(87, 26) error: unreported exception ClassNotFoundException; must be caught or declared to be thrown

I have enabled the J connector in the appengine-web.xml

enter image description here

I'm not sure what I need to do to connect to my SQL db to my Google App Engine. It seems to be more complicated than I thought.

My code:

@ApiMethod(name = "getLesson")
public Lesson getLesson(@Named("id") Long id) {

    Lesson l = new Lesson();

    l.setLessonId(345);
    l.setLessonColour("Blue");
    l.setLessonImage("itshappening.gif");



    String url = null;
    if (SystemProperty.environment.value() ==
            SystemProperty.Environment.Value.Production) {
        // Connecting from App Engine.
        // Load the class that provides the "jdbc:google:mysql://"
        // prefix.
        Class.forName("com.google.cloud.sql.jdbc.Driver");
        url =
                "jdbc:google:mysql://app:instance?user=root";
    } else {
        // Connecting from an external network.
        Class.forName("com.mysql.jdbc.Driver");
        url = "jdbc:mysql://000.000.000.000:3306?user=root";
    }

    Connection conn = null;
    try {
        conn = DriverManager.getConnection(url);
    } catch (SQLException e) {
        l.setLessonDescription(e.getStackTrace().toString());
    }

    try {
        ResultSet rs = conn.createStatement().executeQuery(
                "SELECT 1 + 56");
    } catch (SQLException e) {
        e.printStackTrace();
    }

    logger.info("Calling getLesson method");

    return l;
}

Any help, comments or guidance would be appreciated.

Upvotes: 2

Views: 3130

Answers (2)

TimoStaudinger
TimoStaudinger

Reputation: 42460

The method Class.forName() will throw a ClassNotFoundException when the given class cannot be located.

Since ClassNotFoundException is a checked exception, you actually have to deal with the possibility that one might occur. You can do this either by passing it on to the calling method. To do this, you have to add it to your method's signature:

@ApiMethod(name = "getLesson")
public Lesson getLesson(@Named("id") Long id) throws ClassNotFoundException {
    // ...

Then the method that called the current method has to deal with it.

Alternatively, you can also deal with it directly inside your current method, using a try/catch block:

try {
    // ...

    Class.forName("com.google.cloud.sql.jdbc.Driver");

    // ...
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

In this example, it will simply print the stack trace of the exception to System.err. You can change that error handling to whatever you want.

Upvotes: 1

Mureinik
Mureinik

Reputation: 311528

ClassNotFoundException is a checked exception, so you must either catch it or throw it, as the error says.

To follow your current scheme of exception handling:

try {
    Class.forName("com.google.cloud.sql.jdbc.Driver");
} catch (ClassNotFoundException e) {
    l.setLessonDescription(e.getStackTrace().toString());
}

Upvotes: 1

Related Questions