I am trying to connect to a db2 database from my domino application without using the extension library.
I have created a managed bean that it only connects to the db2 and prints a message on the console.
I call the method of the managed bean from a button on an xpage.
The code in the bean is this:
Class.forName("com.ibm.db2.jcc.DB2Driver");
String url = "jdbc:db2://10.0.1.49:50000/AVIN";
String user = "db2admin";
String password = "ibmdb2";
con = DriverManager.getConnection(url, user, password);
System.out.println("Successful TEST JDBC Connection!!");
I have also configured my build path and added the db2jcc.jar library.
The problem is that i am getting
java.lang.ClassNotFoundException for com.ibm.db2.jcc.DB2Driver
Why is this happening?
Is the DB2 JDBC driver available to your application? I suspect not.
You may need to package the driver in a plugin - within the NSF it will probably hit Java security issues and not work. More recent versions of the Extension Library (the Designer update site install) provide a menu option to Domino Designer to allow you to easily package up a JDBC driver as a plugin, which can then be deployed to your Update Site database.
I strongly recommend using the Extension Library. It will provide robust connection pooling amongst other things. Without it, you may well hit problems already considered and resolved by the experience of the Extension Library developers. If you do hit problems, you may struggle to find anyone with the experience to help you.
Related
We had recently moved to building projects using Maven. Earlier, all the JARs were added in libs folder and added to classpath. While moving to the Maven build, I missed to add a dependency to the 'sqlite-jdbc'. This library is required to read data from a local .db3 file.
As the 'org.sqlite.JBDC' class was loaded by calling the code Class.forName("org.sqlite.JDBC"), there was no compilation error and I deployed the WAR file and servlet failed in the server. I was thinking of a way to find the issue at the compilation time itself to avoid any such mistakes in the future. Can I simply call the JDBC.PREFIX to load the JDBC, so that, If I forget to add the dependency to the pom.xml file, I can find the issue at the compile time, itself?
Is there was difference between Class.forName("org.sqlite.JDBC") vs JDBC.PREFIX to load JDBC class?
No need for Class.forName
There is no generally no need to call Class.forName.
Such calls were used in the early years. Modern Java was changed so that JDBC drivers are automatically loaded and registered with the JVM via the Java Service Provider Interface (SPI) facility.
If you are using books or tutorials advising Class.forName, you may want to obtain more up-to-date learning materials.
DataSource
Furthermore, in Servlet work you generally should not be explicitly accessing the JDBC driver.
Setting the database server address, username, and password would require hard-coding text. When the deployment sysadmins change the IP address, or rotate passwords, your code breaks. You would then have to modify your source code, re-compile, and re-deploy.
Instead, you should externalize such configuration details.
For SQLite, see Using DataSource to connect to SQLite with (Xerial) sqlite-jdbc driver.
JNDI
You can externalize database configuration by using the the DataSource interface. After obtaining a DataSource object at runtime, make database connections by calling its getConnection method. That DataSource object holds the database server address, username, password, and all other settings needed to make a connection to the database.
Obtain a DataSource object at runtime by using JNDI. Your Servlet container may act as the naming/directory server to provide the DataSource object, if your sysadmin so configures it. Or the DataSource can be obtained via JNDI from an external server such as an LDAP server.
Again, the beauty of using DataSource and JNDI is that you as the Servlet programmer need not be involved, or even informed, when the deployment details change.
JDBC driver location
For Servlet work, you generally do not bundle the JDBC driver with your app.
Instead, the JDBC driver goes into a folder managed by your Servlet container. Study the documentation for your particular Servlet container. For Apache Tomcat, see this Answer.
In development, your IDE may need access to the JDBC driver to compile. If so, in your Maven POM, mark the dependency with a <scope>provided</scope> element. This tag tells Maven to omit that dependency from the final build because the dependency will already be present (provided) at runtime.
If you insist on bundling your JDBC driver within the WAR file of your web app, then see the important Comment by Mark Rotteveel.
This topic has been addressed many times on Stack Overflow. Search to learn more.
I tried several tutorials that I could get my hands on, but all of them lead to the same error:
18:28:24,583 INFO [stdout] (default task-1) Database error :No suitable driver found for JDBC:postgresql://localhost:5432/postgres
I have configured the connection following this tutorial: HOW TO SETUP POSTGRESQL DATASOURCE WITH WILDFLY
and tried several ways to fix the problem. I have tried both the management console and the configuration file. The most common solution was trying to add the postgresql-42.2.24.jar to the project structures in modules, but that doesn't solve it. I have created a new simple Java project where I am just trying to connect to the database and it works (I used the same credentials in both places), but when I'm trying to link the server with the DB it's like it doesn't see the driver... When adding a Datasource from Intellij it works perfectly fine (it sees the tables, I can run queries and everything), but I can't get the connection with the server to work.
I'm using Wildfly 24.0.1 Final and Java 8.
Change JDBC to jdbc, it's case-sensitive.
I already know from on JDBC 4.0. and JDK 6, drivers those are found in classpath are automatically loaded. This is the reason we are used to ignoring that Class.forName(dbDriver); line of code when creating JDBC connection.
But recently I installed MySQL Server 8.0.11 and I updated the driver to mysql-connector-java:8.0.11 in my simple Servlet project that runs on tomcat 8.5.30. But it gives me the infamous exception
java.sql.SQLException: No suitable driver found for
jdbc:mysql://localhost:3306/mysql at ...
But all my code was working and fine before. So then I added the Class.forName("com.mysql.jdbc.Driver");
And it works. I think I didn't miss anything. Can anyone explain to me what it might be the reason?
The JDBC 4.0 (and higher) automatic driver loading works only if the driver jar is on the initial (system) class path of the application. If you are using Tomcat, the driver would have to be in the <catalina-home>/lib folder.
If you deploy the driver together with your application, then the driver is on the context classpath of that specific application, and it will need to be explicitly loaded using Class.forName.
But in practice, you should not be using DriverManager.getConnection to create connections in a web application. You should be using a data source (preferably with connection pooling), either created and initialized in code, or in the context or server configuration of Tomcat. In that case this problem wouldn't even surface, because either the data source already knows how to get the driver, or you have to explicitly configure it with the driver to use anyway.
On my local postgres database I can connect with a jdbc url string (from a spring, tomcat, war) like this:
jdbc:postgresql://localhost:5432/mydb?ApplicationName=myapp1.
Then, in pg_activity I can see the application name that started the connection.
However, the company I work for, uses EDB database (flavor of postgres as I understand it). When I deployed my spring application there, the application name did not show up in pg_activity.
So, I reasoned that this is not an accepted connection string argument / parameter. So I googled for it and didn't really find an (alternative) argument to accomplish this. See also https://www.enterprisedb.com/docs/en/9.4/jdbc/Postgres_Plus_Advanced_Server_JDBC_Connector_Guide.1.13.html
Do you know a way to get this working?
The documentation tells us to load JDBC driver like so
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
https://db.apache.org/derby/papers/DerbyTut/embedded_intro.html
But it works fine without and getting the connection straight away
connection = DriverManager.getConnection("jdbc:derby:" + pathDerby + ";create=true");
Why is that?
Version from the log: Booting Derby version The Apache Software Foundation - Apache Derby - 10.13.1.1 - (1765088)
EDIT:
Actually it is needed if you shut down the Derby engine and want to open it again in the same JWM process (I do this all the time in my integration tests)
After shut down
DriverManager.getConnection("jdbc:derby:;shutdown=true");
You should reopen like this
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
connection = DriverManager.getConnection("jdbc:derby:" + pathDerby + ";create=true");
From official documentation:
The DriverManager methods getConnection and getDrivers have been enhanced to support the Java Standard Edition Service Provider mechanism. JDBC 4.0 Drivers must include the file META-INF/services/java.sql.Driver. This file contains the name of the JDBC drivers implementation of java.sql.Driver. For example, to load the my.sql.Driver class, the META-INF/services/java.sql.Driver file would contain the entry:
my.sql.Driver
Applications no longer need to explicitly load JDBC drivers using Class.forName(). Existing programs which currently load JDBC drivers using Class.forName() will continue to work without modification.