While the referenced question is similar it speaks to putting the source code into the database not the class, also I would like to use the TOAD utilities to accomplish this.
So as proof of concept I have been attempting to load a java class into an Oracle 12c Database and access it via an Oracle function.
I opened Eclipse and created new project Hello with class Hello:
public class Hello {
public static String world()
{
return "Hello world";
}
}
I compiled it and now on my client I have
C:\Users\me\workspaces\Hello\bin\Hello.class
I opened up TOAD for an oracle 12c database, then I went to utilities / Java Manager and loaded my class:
TOAD says it successfully loaded. However, I'm not sure if it did.
Next, I went into the TOAD editor and created a function:
CREATE OR REPLACE function "DIR\KBD0010".helloworld RETURN VARCHAR2 AS
LANGUAGE JAVA NAME 'Hello.world () return java.lang.string';
Then I attempted to select it with a sql query:
select helloworld()
from dual;
And then I am getting:
ORA-29540: class Hello does not exist
Related
I am wondering if using loadjava to load the Java package called JSch.jar in an Oracle database and then loading another .java file, that utilizes the JSch package to connect over SSH, would be able to be executed within an Oracle database through a function or procedure.
I ask this before trying because I need to reach out to a DBA to try and load everything. I want to make sure it is doable because I am not very skilled in java as of yet and wouldn't know if something was impossible or if it just needs fixed.
Thanks.
Yes
Use something like:
loadjava -user USERNAME/PASSWORD#SID JSch.jar
Then create a static class method which uses the classes loaded from the Jar file:
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED MyJavaSource AS
import org.millea9805.jsch.JSchSomething;
public class MyClass {
public static String function_name()
{
JSchSomething.doSomething();
return "Something";
}
}
/
Then you can create a PL/SQL wrapper around the static Java method:
CREATE OR REPLACE FUNCTION DO_SOMETHING()
RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'MyClass.function_name() return java.lang.String';
/
A more detailed example using the XZ library to unzip BLOBs is here.
I have loaded the class file of a java program (that fetches data from an excel file and pushes it to a database and making connection to database using values from properties file) into the SQL developer.
Now I am trying to invoke the main method of the class file as below:
CREATE OR REPLACE PROCEDURE dataset
AS LANGUAGE JAVA
NAME 'data_design_1.main()';
It gives the following error:
Error: PL/SQL: Compilation unit analysis terminated
Error(3,1): PLS-00311: the declaration of "data_design_1.main()" is incomplete or malformed
Could anyone tell me why is this error occurring??
Thank you.
I think that the declaration of your main is this
public static void main(String[] args)
so the declaration of your PL/SQL wrapper is wrong.
You haven't posted the Java code
Maybe I'm wrong.
Language: Java
Program: Connecting to a database
Question: I'm trying to connect the sqlite database by following TutorialsPoint tutorial but I keep getting the main class not found error.
Implementation: My code is below followed by my terminal commands and folder structure screenshot. But basically all my files are located in one folder including the sqlite jar file.
import java.sql.*;
public class Test {
public static void main(String[] args) {
Connection c = null;
try{
Class.forName("com.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:test.db");
} catch(Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}
System.out.println("Opened database successfully!");
}
}
Terminal Commands
javac Test.java
java -classpath ".;sqlite-jdbc-3.23.1.jar" Test
Your problem was that you're explicitly trying to load the class com.sqlite.JDBC, whereas the driver class name must've changed somewhere along the way.
JDBC Type 4 drivers have added cleverness which allows you to specify only the connection URL, and the driver loads itself based on the beginning (i.e. jdbc:sqlite). No need to wonder what was the driver class's name.
Rant unrelated to the issue at hand:
Unfortunately people read old tutorials written by less than experts, so we constantly see Class.forName() being used, as well as the more serious issue, which is using Statement instead of PreparedStatement.
My classpath option was incorrect. I was on linux and was trying to do:
java -classpath ".;sqlite-jdbc-3.23.1.jar" Test
the correct way was
java -classpath ".:sqlite-jdbc-3.23.1.jar" Test
colon not semicolon. Unfortunately now it's giving me and error" ClassNotFoundException: com.sqlite.JDBC;
I will look into this.
Thanks for the comments which helped me find the error
I have loaded a Java class into Oracle using the loadjava utility.
This class has some system.out.println messages.
When I execute a method from this class I want to see the the sysout messages.
Where can I find these messages?
System.out and System.err writes to the current trace files.
You can enable output to SQL*Plus or similar with
set serveroutput on size 10000
exec dbms_java.set_output(10000)
See the Java Developer's Guide here.
That said, you should ask yourself, what do I want to log, that my client would not like to see returned in the interface to my procedure?. The answer to that is usually nothing.
I have been able to set up http://www.slf4j.org/ with a JDBC database appender (I am unsure of the specifics).
An Oracle article provides some useful information.
Quote:
Your class:
public class SimpleJava {
public void main(String[] args) {
System.out.println("Here we are");
}
}
Now, compile and load your class:
C:\oracle9i\bin>javac SimpleJava.java
C:\oracle9i\bin>loadjava -user scott/tiger SimpleJava.class
From SQL*Plus, create the PL/SQL wrapper to invoke the newly loaded Java class:
SQL> create or replace procedure call_simplejava
2 as language java
3 name 'SimpleJava.showMessage()';
4 /
Execute the code from SQL*Plus:
SQL> set serveroutput on;
SQL> call dbms_java.set_output(50);
Call completed.
SQL> execute call_simplejava;
Here we are
I'm trying to load some java stored procedures into an Oracle 10g database through JDBC. The statement I'm executing is -
CREATE OR REPLACE JAVA SOURCE NAMED "test.Test" AS
package test;
public class Test {
public static String myMethod(String a) {
return a;
}
};
Running this through TOAD works just fine, but when running through my JDBC client gives the following error -
Exception in thread "Thread-3" java.lang.NullPointerException
at oracle.jdbc.driver.T4C8Oall.getNumRows(T4C8Oall.java:728)
at oracle.jdbc.driver.T4CStatement.execute_for_rows(T4CStatement.java:478)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1028)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:1451)
at ejsdal.CreateDBJavaSQL.executeScript(CreateDBJavaSQL.java:23)
at ejsdal.OperationController.run(OperationController.java:182)
I'm using the java.sql.Statement's "executeUpdate" passing the string in the first code block.
It is possible to load java source through JDBC?
Figured it out - need to set the
statement.setEscapeProcessing(false);
before executing the update. This is because the Java source file's { and } characters are misinterpreted as procedure call syntax by the JDBC driver.