My customer wants to be able to call a jar file from Oracle PL/SQL.
Java 1.6, Oracle 11g R2
How do I do this?
I did a bit of research into loadjava (the program that loads classes into Oracle).
Sounded like a pain in the butt.
So I opted to run my jar outside Oracle but called from Oracle DBMS_SCHEDULER by PL/SQL.
Here's how:
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'testjar',
program_type => 'EXECUTABLE',
program_action => 'C:\MYSTUFF\testjar.bat',
enabled => TRUE,
comments => 'test testjar'
);
END;
/
begin
dbms_scheduler.create_job
(job_name => 'testjar_job',
program_name=> 'testjar',
enabled=>true,
auto_drop=>false,
comments=>'Only run immediately by dbms_scheduler.run_job');
end;
/
begin
dbms_scheduler.run_job('testjar_job',TRUE);
end;
/
After playing around I found out that the schema JAR_NAME.jar///ClassName.methodName(.... works.
So for example:
Function do()
return String
AS
LANGUAGE java
NAME 'my_jar.jar///MyClass.myMethod() return oracle.sql.String';
Note that it seems like some jar name files does not work. For example I had problems with a "-" in jar.
Related
I am trying to get data from SQL Server database table and show it as part of choice parameter as part of a Jenkins Job Build Parameters that I am trying to setup.
I am trying to figure out how to use Extensible Choice for this.
The Choice provider I used is "System Groovy Choice Parameter"
import groovy.sql.Sql
import com.microsoft.sqlserver.jdbc.SQLServerDriver
def output = []
def configuration = [
'dbInstance' : 'servername',
'dbPort' : 0000,
'dbName' : 'dbName',
'dbUser' : 'dbUser',
'dbPass' : 'dbPass'
]
def sql = Sql.newInstance("jdbc:sqlserver://${configuration.dbInstance}:${configuration.dbPort};"
+ "databaseName=" + configuration.dbName,
configuration.dbUser, configuration.dbPass,
'com.microsoft.sqlserver.jdbc.SQLServerDriver')
String sqlString = "SELECT * FROM dbTable"
sql.eachRow(sqlString){ row -> output.push(row[0])
}
return output.sort()
Below is the error I see. Which I understand I see because the jdbc driver is not present. I downloaded the driver from the link below:
https://www.microsoft.com/en-us/download/details.aspx?id=11774
I followed the instructions as to where it should be unzipped to as mentioned in the instructions.
I saw that the CLASSPATH variable is missing, so i went ahead and created the Environment variable with path: "C:\Program Files\sqljdbc_6.0\enu\sqljdbc.jar"
Error: unable to resolve class com.microsoft.sqlserver.jdbc.SQLServerDriver
How do i make sure that the script runs successfully and returns all the data to Extensible Choice. If there is anyother way to do this, I am open to suggestions.
Thank you very much
To resolve the issue I had to copy the "sqljdbc4.jar" file to the following location "C:\Java\jdk1.8.0_92\jre\lib\ext" since that is the path where the JAVA searches for the external jars. Use 4th version for the file which will have 4 in the file name as above as that is version Jenkins supports.
I have next procedure to rename file on google drive, using REST with Google api. It's working with Delphi xe7.
Unfortunately with RAD 10 this procedure raise an exeption:
Java.net.ProtocolException unknown method 'Patch'... . I've read that it's because of java libraries. I changed paths
Tools-options-sdk manager - java to XE 7 java libraries, but it's useless.
Don't want to play Russian Roulette with random changing/updating setting, can someone tell me, what i should exactly update/change in RAD settings.
Thank you.
procedure ServerPatchDriveFile;
var
Folder : TJSONObject ;
FolderDest, itemmm : TJSONObject ;
parents: TJSONArray ;
begin
form2.RESTResponseDataSetAdapter1.AutoUpdate := false;
form2.RESTRequest1.Params.Clear;
form2.RESTRequest1.ClearBody;
form2.RESTClient1.AutoCreateParams:=false;
form2.RESTClient1.Accept:= '';
form2.RESTClient1.ContentType:= '';
form2.RESTRequest1.Method:= rmPATCH;
Form2.RESTClient1.BaseURL:='https://www.googleapis.com/drive/v2/files/{FileId}';
form2.RESTRequest1.Resource := '';
form2.RESTRequest1.Params.AddUrlSegment('fileId', UntitledId);
Parents:= TJSONArray.Create;
itemmm := TJSONObject.Create;
itemmm.AddPair(TJSONPair.Create('id', form2.EditIdFOlder.Text));
Parents.AddElement((itemmm));
Folder:= TJSONObject.create;
Folder.AddPair(TJSONPair.Create('title', 'Myfile'));
Folder.AddPair(TJSONPair.Create('parents', Parents));
form2.RESTRequest1.AddBody(Folder);
try
form2.RESTRequest1.Execute;
except
on e: Exception do
begin
ShowMessage(e.Message);//Show Exception
end;
end;
Folder.free;
Application.ProcessMessages;
end;
When I start ensime in Emacs, it immediately crashes saying:
'"java"' is not recognized as an internal or external command,
operable program or batch file.
Process *inferior-ensime-server-documents* exited abnormally with code 1.
This is strange, because when I write java in cmd (in Windows 8), it runs. I added java both to Emacs's exec-path and the system's Path variables. Also I'm surprised it is in triple quotes, '"java"'. Do these quotes interfere? And what to do with them?
My .ensime file (created via sbt gen-ensime) looks like this:
(
:root-dir "C:\\Users\\leokr_000\\Documents\\skala"
:cache-dir "C:\\Users\\leokr_000\\Documents\\skala\\.ensime_cache"
:name "skala"
:java-home "C:\\Program Files\\Java\\jdk1.7.0_07\\bin"
:java-flags ("-Xmx512M" "-XX:MaxPermSize=256m" "-XX:ReservedCodeCacheSize=128m" "- Dsbt.log.format=true")
:reference-source-roots nil
:scala-version "2.10.4"
:compiler-args nil
:subprojects ((
:name "skala"
:module-name "skala"
:source-roots ("C:\\Users\\leokr_000\\Documents\\skala\\src\\main\\scala" "C:\\Users\\leokr_000\\Documents\\skala\\src\\main\\java" "C:\\Users\\leokr_000\\Documents\\skala\\src\\test\\scala" "C:\\Users\\leokr_000\\Documents\\skala\\src\\test\\java")
:target "C:\\Users\\leokr_000\\Documents\\skala\\target\\scala-2.10\\classes"
:test-target "C:\\Users\\leokr_000\\Documents\\skala\\target\\scala-2.10\\test-classes"
:depends-on-modules nil
:compile-deps ("C:\\Users\\leokr_000\\.sbt\\boot\\scala-2.10.4\\lib\\scala-library.jar")
:runtime-deps nil
:test-deps nil
:reference-source-roots ("C:\\Users\\leokr_000\\.ivy2\\cache\\org.scala-lang\\scala-library\\srcs\\scala-library-2.10.4-sources.jar")))
)
Your :java-home is wrong, I don't know how you can run anything in sbt with this setup. Remove the \\bin from this and investigate why it is being incorrectly generated.
I am having trouble using Create Function Command for Derby Database.
To start with I tried
CREATE FUNCTION TO_DEGREES(RADIANS DOUBLE) RETURNS DOUBLE
PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA
EXTERNAL NAME 'java.lang.Math.toDegrees'
and then
SELECT TO_DEGREES(3.142), BILLNO FROM SALEBILL
This works absolutely fine.
Now I tried making my own function like this :
package SQLUtils;
public final class TestClass
{
public TestClass()
{
}
public static int addNos(int val1, int val2)
{
return(val1+val2);
}
}
followed by
CREATE FUNCTION addno(no1 int, no2 int) RETURNS int
PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA
EXTERNAL NAME 'SQLUtils.TestClass.addNos'
and then
SELECT addno(3,4), BILLNO FROM SALEBILL
This gives an Exception
Error code -1, SQL state 42X51: The class 'SQLUtils.TestClass' does not exist or is inaccessible. This can happen if the class is not public.
Error code 99999, SQL state XJ001: Java exception: 'SQLUtils.TestClass: java.lang.ClassNotFoundException'.
Line 6, column 1
I have made a jar file of the project containing the above Class. I may be wrong but the conclusion that I can draw from this is that this jar file needs to be in some classpath. But in which classpath and how to add it to a classpath, I am not able to understand.
I tried copying the jar file to jdk\lib folder, jre\lib folder, jdk\jre\lib folder but to no avail.
Can someone please point me in the right direction ?
I am using NetBeans IDE 7.1.2, jdk 1.7.0_09, Derby version 10.8.1.2 in Network mode. The applications and data are on a Server. I access them from Netbeans installed on client computer.
public class HelloWorld{
public static void add(int a, int b){
System.out.println(a+b);
}
}
and I load it into oracle via
loadjava -user system/admin Helloworld.class
This words fine.
After that I write this procedure:
create or replace
PROCEDURE start_helloworld(a in number, b in number)
AS language java
name 'HelloWorld.add(int,int)';
I want to be able to call the procedure in PL/SQL:
exec start_helloworld(1,1);
but it gives the error I mentioned.
You can't do console output from Oracle java code, since it's running within the database. Perhaps if you passed in and in/out variable, assigned the output of your arithmetic assignment to the variable and output that in the calling PL/SQL block:
var mynum NUMBER
exec start_helloworld(1,1,:mynum);
print mynum;
You would of course need to modify your java and PL/SQL wrapper to add the new parameter:
public static void add(int a, int b, int c){
c = a+b;
}
and
create or replace
PROCEDURE start_helloworld(a in number, b in number, c in out number)
AS language java
name 'HelloWorld.add(int,int,int)';
I am not an Oracle expert by any means but I have hit this issue recently so I just wanted to comment. For some reason I can't just leave a comment, So here's my answer.
Comment:
When I get the Ora-29516 error, it comes with a reason description. Is there more to the error when you get it?
Answer:
If your Aurora Assertion error comes with the reason "Uncaught exception System error: java/lang/UnsupportedClassVersionError" =>
I get this error when the version of Java I used to compile the class file isn't the same as the version of Java in Oracle (1.5.0 in 11g). To be sure you match perfectly, let Oracle compile the class for you. You'll get two benefits: 1) You will be sure the Java version matches exactly. 2) You'll have the source code loaded as a database "JAVA SOURCE" object for future reference. For security purposes, you may want to lock it down.
loadjava -user scott/tiger -resolve HelloWorld.java
By using the source file with the resolve option, Oracle will create the source object and compile the code for the class object. If you leave out the -resolve option, Oracle will create the source object and only compile it when it is called. I presume this may have good flexibility options but performance drawbacks.
This error occurs because incompatibility of different java versions in oracle and java compiler.
-> oracle version:
--TO CHECK JAVA VERSION IN ORACLE
SELECT dbms_java.get_ojvm_property(PROPSTRING=>'java.version') FROM dual;
FOLLOW THIS STEPS :
//java
class simple{
public static String world(){
return("Hello Java");
}
}
Insted of loading class Simple load your java directly,
STEP1 :
loadjava -user system/admin simple.java
STEP2:
then > create one procedure
CREATE OR REPLACE PROCEDURE PROC_DEMO as
language java
name 'simple.world()';
/
STEP3:
declare -- Parameter declaration
RESULT VARCHAR2(2000);
begin
-- Please customize initialization
-- Call the procedure/function
RESULT := FUNC_DEMO;
-- Print out the results
dbms_output.put_line( 'RESULT = ' || SUBSTR( RESULT, 1, 255));
end;