0

I am having an awful lot of trouble connecting to an RDS via Java for the first time. The full workflow is: Api-gateway method is invoked, calls the appropiate Lambda function (lambda in the aws sense), the lambda function connects to a Relational Database already running on AWS, and performs a query.

This is the big picture, currently I am having an awful lot of trouble configuring eclipse with maven with the right dependencies and configurations to connect to the database. I am following this guide. It even has simple code to try, which I do not manage to run succesfully.

My question would be: what do I need to put in my POM, what in my build path, and why would the code not even attempt a connection, and when I modify the code or use other examples I get errors such as "ClassNotFoundException: com.mysql.jdbc.Driver".

What is the proper way to configure the connection from java to the RDS?

Thank you in advance.

Example of code as seen in the tutorial:

private static Connection getRemoteConnection() {
    if (System.getenv("RDS_HOSTNAME") != null) {
      try {
      Class.forName("org.mysql.Driver");
      String dbName = System.getenv("RDS_DB_NAME");
      String userName = System.getenv("RDS_USERNAME");
      String password = System.getenv("RDS_PASSWORD");
      String hostname = System.getenv("RDS_HOSTNAME");
      String port = System.getenv("RDS_PORT");
      String jdbcUrl = "jdbc:mysql://" + hostname + ":" + port + "/" + dbName + "?user=" + userName + "&password=" + password;
      logger.trace("Getting remote connection with connection string from environment variables.");
      Connection con = DriverManager.getConnection(jdbcUrl);
      logger.info("Remote connection successful.");
      return con;
    }
    catch (ClassNotFoundException e) { logger.warn(e.toString());}
    catch (SQLException e) { logger.warn(e.toString());}
    }
    return null;
  }

The biggest trouble came from that code not working at all, and the moment I remove the line " Class.forName("org.mysql.Driver");

Example of POM I am using. I have also tried adding the jdbc driver in different ways to my build path with no avail.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.amazonaws.lambda</groupId>
    <artifactId>demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <testFailureIgnore>true</testFailureIgnore>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                    <forceJavacCompilerUse>true</forceJavacCompilerUse>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.amazonaws</groupId>
                <artifactId>aws-java-sdk-bom</artifactId>
                <version>1.11.277</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-events</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.1.0</version>
        </dependency>
    </dependencies>
</project>

I also have the amazon plugin for eclipse and am running lambda functions from there, giving it a small json that the code does not use just so it can run.

monkey intern
  • 705
  • 3
  • 14
  • 34
  • Well, you never compile Postgres or MySQL dependencies – OneCricketeer Feb 27 '18 at 09:40
  • I am afraid I do not understand the comment. Do you mean to say that I am not doing and I should, or that I should never do it? Pardon my English – monkey intern Feb 27 '18 at 09:42
  • You might want to go over a Maven tutorial. It's not entirely clear *when* you get that error... Take out the fact that you are using RDS, the code itself has nothing to do with AWS... It's just regular JDBC code, (you can run your own database on your own computer) and you could be using a Postgres or a Mysql database, and we really can't answer if you're just guessing which one you need – OneCricketeer Feb 27 '18 at 13:25
  • The code posted there is straight out of the AWS official guidelines to connect a local Java-Maven-Eclipse proyect with RDS, in my case specifically with a mysql instance. I am sorry if I was unclear but I am not really guessing, just trying to follow intrusctions since this whole lambda-function to connect to some RDS in the cloud is new to me – monkey intern Feb 27 '18 at 13:43

2 Answers2

1

You're using both

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

And jdbc:postgresql which makes me think you're not sure what database you're actually using...

Go look at the AWS console, or talk to the the person who set up the RDS database before trying to copy various tutorials.

Secondly, remove the second definition for maven-shade-plugin.

Once you know that database you are using search for it's Maven dependencies

More importantly, the issue is not RDS, it's just knowing how to add classes to the classpath

And it's not clear what jar file you're running (or just running code in Eclipse itself), but after mvn clean package, you must run the larger JAR file in the target folder

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • I simply edited poorly the code, since I wanted to give an example as clean as possible, and the example comes with progresql, that is not the problem with what I am running. On the other hand, in the first link you provided, there is no accepted answer and every solution appoints to some different solution: POM, build path, adding jars... I have tried many/most of those things, probably not in the right order, but so far have not found a solution. – monkey intern Feb 27 '18 at 13:55
  • 1
    Well, adding the POM dependencies for Postgres, shown in the other answer here, would work. Add those work in any IDE, so I would suggest not using Eclipse's methods of "Add external JAR" to the project classpath. Then, please clarify how you run the application. From Eclipse Maven targets, the terminal, or somewhere else? And how are you setting up the environment variables? – OneCricketeer Feb 27 '18 at 14:02
  • Great question, it actually took me a while to figure out. To run the code, once you configured the eclipse plugin with your keys, with AWS you can create a lambda function and then, you can give it - by hand (it gives you a menu) - values to your variables, so System.getenv() can catch them. Once that set up is done, I go to my code, right click, select "AWS lambda", then "run function on lambda" and mark "show the logs". – monkey intern Feb 27 '18 at 14:12
  • And as I said, matching everything I've been told to mysql, which is what I need, only works if I remove the line of code "Class.forName("org.mysql.Driver");" I do not get a connection but at least I do not get an exception, and the code runs. Not sure how to proceed from here :( – monkey intern Feb 27 '18 at 14:14
  • So, you're running the JAR from AWS itself? And "which" JAR file? Because the shade plugin makes multiple (or at least should, given a certain set up) – OneCricketeer Feb 27 '18 at 14:16
  • 1
    If the code runs without it, read https://stackoverflow.com/questions/33391496/is-class-forname-mechanism-needed – OneCricketeer Feb 27 '18 at 14:18
  • I am running from eclipse itself, and the first days I spent a lot of time configuring the jars, since I was having trouble. I did not know there were more than 2 created, I was told to use the so called "far jar" so aws has all libraries included, for optimization purposes (since you pay the longer the code runs). As of right now, I am unsure which specific jar is running, tbh. – monkey intern Feb 27 '18 at 14:24
  • I know I am annoying, but currently what I get just before doing "con = DriverManager.getConnection(jdbcUrl2);" which is the object Connection iniated at null value, when I print where am I trying to connect this is what I get::: jdbc:mysql://cmf6lelghjzq.eu-west-1.rds.amazonaws.com:3306/botdb?user=bot&password=valuePWexample. And after trying to stablish connection, the object is still null and I get nothing. – monkey intern Feb 27 '18 at 14:30
  • It's been years since I've used eclipse, but the fat jar is correct. However, I'm not sure if Eclipse actually runs that one. But if it didn't that explains the errors you see – OneCricketeer Feb 27 '18 at 14:30
0

ClassNotFound means that you don't have the proper class (or library) into your project.

You should add the maven dependencies for postgres or mysql drivers and ensure that they appear on the classpath

The pom must have something like this:

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.2.1</version>
</dependency>

Or

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.6</version>
</dependency>
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • I get the exam same message after adding the mysql dependency. In other threads the mention it is not the mysql connector, it is the bin. In others, X other thing. I feel lost and the tutorial examples come in python, or worse, with AWS CLI. I fail to see how a connection to a database can be this complicated :S – monkey intern Feb 27 '18 at 12:04
  • Basically if I remove this line " Class.forName("com.mysql.jdbc.Driver"); " the code works better. I still do not get a connection, but it does not fail because of that. – monkey intern Feb 27 '18 at 12:09
  • "ensure that they appears inside the WEB-INF/lib folder"....? Well, this does not need to be a web app, so that's wrong – OneCricketeer Feb 27 '18 at 13:28