| Lesson 3 | Java and Oracle |
| Objective | Explain external Java connections, stored integration, and Oracle JVM memory |
Java integrates with Oracle in two execution environments. An external Java application runs in its own JVM and connects to a database service through JDBC. Stored Java runs inside the database using Oracle JVM (OJVM), where SQL and PL/SQL can invoke published Java methods. Both approaches remain relevant in Oracle AI Database 26ai, but they have different deployment, resource, and security requirements.
For a web service, an external application tier is usually a practical starting point: it can scale and deploy independently of the database. Stored Java is an option when a suitable Java routine needs to execute within a database session. Choose according to the workload rather than assuming that either location is always faster.
Stored Java requires Oracle JVM to be installed and available in the target database environment. Java classes are loaded into a database schema, and a call specification publishes a Java method as a SQL-callable function or procedure. The specification maps SQL parameters and return values to compatible Java types.
Stored Java can use the server-side internal JDBC driver to access SQL and PL/SQL in its existing database session and transaction. This local access does not require a new network connection. The internal driver does not provide remote database connections or automatic commits. Define transaction ownership explicitly and close statements and result sets when finished; do not treat the default internal connection as a borrowed application-pool connection.
Before deploying a library into OJVM, verify its Java version, dependencies, supported APIs, and required permissions. An external application's JDK version does not establish which bytecode or libraries the database JVM supports. Filesystem and network access also require appropriate database permissions and may be restricted by the cloud service.
The JDBC API gives Java code a consistent way to submit SQL, bind parameters, process results, and call stored procedures. The driver and connection behavior depend on where the Java code executes.
| Execution location | Typical connection | Key distinction |
|---|---|---|
| Application JVM outside the database | Oracle JDBC Thin to a database service | Uses a network connection; configure authentication, transport security, and optional application pooling. |
| Oracle JVM accessing its own database session | Server-side internal JDBC | Uses the existing session and local transaction rather than establishing a separate network session. |
| Stored Java accessing a remote database or a separate session | Server-side JDBC Thin, where permitted | Creates a separate connection with its own configuration and transaction context. |
The JDBC Thin driver is pure Java and does not require an Oracle Client installation. It is used for both on-premises and cloud databases. OJVM is not required merely to accept connections from an external Java application.
Oracle JVM can share reusable class and method definitions while maintaining mutable Java state for individual database sessions. For example, a static Java field can retain a value across calls in one session without becoming a global variable shared by every database session.
The Java pool is part of the System Global Area (SGA). It supports Oracle JVM memory requirements, including shared definitions and, depending on the server mode, Java session storage. The diagram is a conceptual view, not a claim that every Java object resides in one SGA area.
This distinction matters when connections are reused. A logical request in a web application is not necessarily a new database session. Avoid assuming that session state is automatically cleared between users of an application pool. Prefer explicit request data and use the pool's supported session initialization and reset mechanisms when state is necessary.
Keep large data operations close to the data when practical, but measure the complete workload. Moving CPU-intensive application processing into the database can increase contention rather than reduce it. Browser applets are not part of this architecture; browser clients communicate with application or REST endpoints.
External Java applications can connect to Oracle databases on OCI using JDBC Thin. Applications may run on virtual machines, in containers, or on other supported application platforms. Configure the database service, reachable network path, authentication, and client libraries for the deployment.
Configure encryption for each network hop. HTTPS to an application server does not secure that server's database connection automatically. Keep application credentials outside source code and grant only the required database privileges.
Universal Connection Pool (UCP) runs in the Java application and reuses physical database connections. Create and manage a pool at application startup, borrow a connection for a unit of work, and return it promptly. Size the total connections across all application instances against database capacity.
Database Resident Connection Pooling (DRCP) reuses server processes and sessions on the database side. It can complement application pooling for suitable workloads. It is not the Java pool, and it should not be enabled simply because an application uses Java.
Using DRCP requires an available, started server-side pool, a pooled connection request such as SERVER=POOLED in the connect descriptor, and appropriate client configuration. Setting oracle.jdbc.DRCPConnectionClass alone does not request a pooled server. Review session-state compatibility before combining DRCP with stateful application behavior.
The following class separates pool creation from query execution. Call createPool() once during application startup and reuse the returned pool. The query assumes that PRODUCTS has PRODUCT_ID, NAME, and PRICE columns and that the application account has permission to read them.
Install compatible Oracle JDBC and UCP libraries for the application's JDK. Configure APP_DB_URL, APP_DB_USER, and APP_DB_PASSWORD through deployment configuration. Where a wallet-based TNS alias is used, an example URL is jdbc:oracle:thin:@mydb_low?TNS_ADMIN=/opt/app/wallet; substitute an actual service alias and configure the required wallet libraries and credentials. The pool settings below are illustrative.
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceFactory;
public final class ProductRepository {
public static PoolDataSource createPool() throws SQLException {
PoolDataSource pool = PoolDataSourceFactory.getPoolDataSource();
pool.setConnectionFactoryClassName(
"oracle.jdbc.pool.OracleDataSource");
pool.setURL(requiredEnvironment("APP_DB_URL"));
pool.setUser(requiredEnvironment("APP_DB_USER"));
pool.setPassword(requiredEnvironment("APP_DB_PASSWORD"));
pool.setInitialPoolSize(1);
pool.setMinPoolSize(1);
pool.setMaxPoolSize(10);
pool.setConnectionWaitTimeout(10);
pool.setValidateConnectionOnBorrow(true);
return pool;
}
public static void listProducts(PoolDataSource pool,
BigDecimal minimumPrice)
throws SQLException {
String sql = "SELECT product_id, name FROM products "
+ "WHERE price > ?";
try (Connection connection = pool.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setBigDecimal(1, minimumPrice);
try (ResultSet results = statement.executeQuery()) {
while (results.next()) {
System.out.println(results.getLong("product_id")
+ ": " + results.getString("name"));
}
}
}
}
private static String requiredEnvironment(String name) {
String value = System.getenv(name);
if (value == null || value.isEmpty()) {
throw new IllegalStateException("Missing configuration: " + name);
}
return value;
}
}
Try-with-resources closes the result set and statement and returns the borrowed connection to UCP. The example performs a read-only query and does not configure DRCP. For transactional writes, define commit and rollback handling explicitly, or use the application's transaction manager. Manage pool shutdown through the application lifecycle and its supported UCP integration.
Java applications can access relational tables and JSON-relational duality views through JDBC. They can also generate embeddings with compatible models or services and store and query VECTOR data using a driver version that supports the required operations. These capabilities do not require the Java application itself to run inside OJVM.
The central design decision is where code executes and who owns its resources. External Java uses an application JVM and network database connections. Stored Java uses Oracle JVM within database sessions. SQL and PL/SQL provide database operations in either design, while connection pooling and Java memory management remain separate concerns.