Calling shell script from PL/SQL, but shell gets executed as grid user, not oracle - sql

I am trying to execute a shell script from inside the Oracle database using Runtime.getRuntime().exec.
Oracle 11.2.0.4 EE running on Red Hat 5.5
CREATE OR REPLACE procedure pr_executa_host(p_cmd varchar2)
as language java name 'Util.RunThis(java.lang.String)';
/
public class Util extends Object
{
public static int RunThis(java.lang.String args)
{
Runtime rt = Runtime.getRuntime();
int rc = -1;
try
{
Process p = rt.exec(args);
int bufSize = 4096;
BufferedInputStream bis =
new BufferedInputStream(p.getInputStream(), bufSize);
int len;
byte buffer[] = new byte[bufSize];
// Echo back what the program spit out
while ((len = bis.read(buffer, 0, bufSize)) != -1)
System.out.write(buffer, 0, len);
rc = p.waitFor();
}
catch (Exception e)
{
e.printStackTrace();
rc = -1;
}
finally
{
return rc;
}
}
}
/
The permissions granted on java to db user SCOTT:
kind grantee type name action
GRANT SCOTT java.io.FilePermission /webstart/mn500/* readFileDescriptor
GRANT SCOTT java.io.FilePermission /webstart/mn500/* read,write,execute
GRANT SCOTT java.io.FilePermission /webstart/mn500/* writeFileDescriptor
GRANT SCOTT java.io.FilePermission /webstart/mn500/CONCLUIDO/MN457560/executa.sh execute
GRANT SCOTT java.lang.RuntimePermission * writeFileDescriptor
GRANT SCOTT java.lang.RuntimePermission /webstart/mn500/CONCLUIDO/MN457560/executa.sh execute
The shell script executa.sh, which is the one I'm trying to execute:
#!/bin/sh
echo i am `/usr/bin/whoami`
echo environment `/bin/env`
/bin/date>>/webstart/mn500/CONCLUIDO/MN457560/test.txt
The permissions on the directory:
p08[oracle] $ ls -larth /webstart/mn500/CONCLUIDO/MN457560
-rw-r--r-- 1 oracle oinstall 1 Jul 29 12:03 test.txt
-rwxr-xr-x 1 oracle orafiles 430 Jul 29 12:04 executa.sh
drwxr-xr-x 2 oracle orafiles 4.0K Jul 29 12:04 .
The thing is, when I execute the procedure pr_executa_host, it runs the shell script as grid os
user, not oracle! (although it keeps oracle environment variables, like it did a 'su grid -m'
before executing the shell script)
Since grid doesn't have write privileges on neither the directory, nor the file, the script doesn't
do anything, the test file stays unaltered. Take a look:
begin
dbms_java.set_output(1000000);
pr_executa_host('/webstart/mn500/CONCLUIDO/MN457560/executa.sh');
dbms_lock.sleep(2);
end;
/
i am grid
environment HOSTNAME=p08.XXXXXXXXXXXX.com.br SHELL=/bin/bash TERM=xterm HISTSIZE=1000
SSH_CLIENT=10.141.112.28 56029 22 NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252 QTDIR=/usr/lib64/qt-3.3
QTINC=/usr/lib64/qt-3.3/include SSH_TTY=/dev/pts/0 USER=oracle
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;0
1:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01
;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*
.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31
:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7
z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01
;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;3
5:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*
.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=
01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35
:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.a
ac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=
01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36: ORACLE_SID=sigepshm
ORACLE_BASE=/oracle ORACLE_HOSTNAME=P08 PATH= MAIL=/var/spool/mail/oracle
TNS_ADMIN=/grid/product/11.2.0/grid/network/admin PWD=/oracle/product/11.2.0/db/dbs
KDE_IS_PRELINKED=1 LANG=en_US.UTF-8 ORA_NET2_DESC=27,30 KDEDIRS=/usr ORACLE_TERM=xterm
ORACLE_SPAWNED_PROCESS=1 HISTCONTROL=ignoredups SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
HOME=/home/oracle SHLVL=2 GRID_HOME=/oracle/product/11.2.0/grid LOGNAME=oracle CVS_RSH=ssh
QTLIB=/usr/lib64/qt-3.3/lib SSH_CONNECTION=10.141.112.28 56029 10.147.0.8 22
CLASSPATH=/oracle/product/11.2.0/db/JRE:/oracle/product/11.2.0/db/jlib:/oracle/product/11.2.0/db/rdb
ms/jlib LESSOPEN=|/usr/bin/lesspipe.sh %s DISPLAY=localhost:10.0
ORACLE_HOME=/oracle/product/11.2.0/db G_BROKEN_FILENAMES=1 _=/bin/env
Why is the java inside the database calling unix commands as grid user, not oracle?
Thanks a lot for your help,
Stolf

The issue, as pointed out in the comments, is that Runtime.getRuntime().exec runs throught EXTPROC, and thus through the Grid Listener. Since we have OS user isolation between DB and GRID on our new configuration, this raised a permission problem on the FS.
The solution to this is one of the bellow:
Fix FS permission to let grid user write the files and change umask to something like 774 or 664, so both grid and oracle users will be able to modify the files later;
change sudoers file and allow grid to execute the commands needed as oracle without password and change shell script to include sudo;
create a new listener on DB Home on another port and change TNSNAMES.ORA entry to point to the new port. Then extproc will be executed as OS user oracle. You will have to manually edit LISTENER.ORA on $OH and start it with lsnrctl, because listeners registered with srvctl will always be started by grid ;
change main listener to the db home. I don't recommend that (see item above).
[EDIT]
As pointed out by #AlexPoole and #jonearles, there are two other options that weren't fit for my case, but might be for others:
if you run the script locally on sqlplus, setting ORACLE_SID, the FS access will be made by the OS user running sqlplus. So you can run as oracle, or some other user and fix the FS permissions;
if you schedule a job on dbms_job scheduler as SYS, the task will be executed by oracle (this behavior may be version dependent, so further testing is needed).
Regards,
Daniel Stolf

On further investigation it runs the script as the OS user that started the session; but the server user, not the client osuser seen in v$session.
If you connect locally through SQL*Plus, without going through SQL*Net, the shell script runs as your own OS user, not grid or oracle, unless you're logged into the box as one of those. So when I execute the procedure as myself, the script reports i am apoole.
When you run remotely though, the OS user for the session is the listener owner, which by default in a Grid environment is going to be grid. And you see the environment of the grid user when the listener was started.
So if you're going to be executing this manually, remotely through a SQL*Net-connected client then the options in your own answer are valid. You can move the DB listener to run under the oracle account, or create a new listener under that account, and connect via that. Then the script will execute as oracle when invoked from any session connected via that listener. Or make the OS permissions/sudo work for you.
If you will or might execute it from a local session without going through SQL*Net then you'd need to make the OS permissions valid for any user that might invoke it - assuming you won't be running it from SQL*Plus launched from the oracle account. The listener isn't part of the picture, so the grid user isn't a factor.
This is when it's run as an anonymous block; as #jonearles pointed out in a comment on the question, the behaviour for scheduled jobs is different. By default it would execute the script as nobody, which would mean you'd have to relax the OS permissions even more.

Related

Static Hangfire RecurringJob methods in LINQPad are not behaving

I have a script in LINQPad that looks like this:
var serverMode = EnvironmentType.EWPROD;
var jobToSchedule = JobType.ABC;
var hangfireCs = GetConnectionString(serverMode);
JobStorage.Current = new SqlServerStorage(hangfireCs);
Action<string, string, XElement> createOrReplaceJob =
(jobName, cronExpression, inputPackage) =>
{
RecurringJob.RemoveIfExists(jobName);
RecurringJob.AddOrUpdate(
jobName,
() => new BTR.Evolution.Hangfire.Schedulers.JobInvoker().Invoke(
jobName,
inputPackage,
null,
JobCancellationToken.Null),
cronExpression, TimeZoneInfo.Local);
};
// psuedo code to prepare inputPackage for client ABC...
createOrReplaceJob("ABC.CustomReport.SurveyResults", "0 2 * * *", inputPackage);
JobStorage.Current.GetConnection().GetRecurringJobs().Where( j => j.Id.StartsWith( jobToSchedule.ToString() ) ).Dump( "Scheduled Jobs" );
I have to schedule in both QA and PROD. To do that, I toggle the serverMode variable and run it once for EWPROD and once for EWQA. This all worked fine until recently, and I don't know exactly when it changed unfortunately because I don't always have to run in both environments.
I did purchase/install LINQPad 7 two days ago to look at some C# 10 features and I'm not sure if that affected it.
But here is the problem/flow:
Run it for EWQA and everything works.
Run it for EWPROD and the script (Hangfire components) seem to run in a mix of QA and PROD.
When I'm running it the 'second time' in EWPROD I've confirmed:
The hangfireCs (connection string) is right (pointing to PROD) and it is assigned to JobStorage.Current
The query at the end of the script, JobStorage.Current.GetConnection().GetRecurringJobs() uses the right connection.
The RecurringJob.* methods inside the createOrReplaceJob Action use the connection from the previous run (i.e. EWQA). If I monitor my QA Hangfire db, I see the job removed and added.
Temporary workaround:
Run it for EWQA and everything works.
Restart LINQPad or use 'Cancel and Reset All Queries' method
Run it for EWPROD and now everything works.
So I'm at a loss of where the issue might lie. I feel like my upgrade/install of LINQPad7 might be causing problems, but I'm not sure if there is a different way to make the RecurringJob.* static methods use the 'updated' connection string.
Any ideas on why the restart or reset is now needed?
LINQPad - 5.44.02
Hangfire.Core - 1.7.17
Hangfire.SqlServer - 1.7.17
This is caused by your script (or a library that you call) caching something statically, and not cleaning up between executions.
Either clear/dispose objects when you're done (e.g., JobStorage.Current?) or tell LINQPad not to re-use the process between executions, by adding Util.NewProcess=true; to your script.

UMDF PnP Driver creates no trace logs

Im trying to create trace log messages for this Idd Sample Driver. I am following this document.
I add WPP_INIT_TRACING(pDriverObject, pRegistryPath) to the DriverEntry, and WPP_CLEANUP(pDriverObject)to the EvtCleanupCallback.
_Use_decl_annotations_
void DriverContextCleanup(WDFOBJECT DriverObject)
{
UNREFERENCED_PARAMETER(DriverObject);
DoTraceMessage(MYDRIVER_ALL_INFO, "Tracing Fini Success");
WPP_CLEANUP(WdfDriverWdmGetDriverObject(DriverObject));
}
_Use_decl_annotations_
extern "C" NTSTATUS DriverEntry(
PDRIVER_OBJECT pDriverObject,
PUNICODE_STRING pRegistryPath
)
{
WDF_DRIVER_CONFIG Config;
NTSTATUS Status;
WDF_OBJECT_ATTRIBUTES Attributes;
WDF_OBJECT_ATTRIBUTES_INIT(&Attributes);
Attributes.EvtCleanupCallback = DriverContextCleanup;
WDF_DRIVER_CONFIG_INIT(&Config,
IddSampleDeviceAdd
);
WPP_INIT_TRACING(pDriverObject, pRegistryPath);
DoTraceMessage(MYDRIVER_ALL_INFO, "Tracing Init . . .");
Status = WdfDriverCreate(pDriverObject, pRegistryPath, &Attributes, &Config, WDF_NO_HANDLE);
if (!NT_SUCCESS(Status))
{
DoTraceMessage(MYDRIVER_ALL_INFO, "Tracing Init Failed");
WPP_CLEANUP(pDriverObject);
return Status;
}
DoTraceMessage(MYDRIVER_ALL_INFO, "Tracing Init Success");
return Status;
}
I add some DoTraceMessage() calls with a flag of MYDRIVER_ALL_INFO to the DriverEntry and DeviceEntry.
NTSTATUS IddSampleDeviceD0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
{
UNREFERENCED_PARAMETER(PreviousState);
// This function is called by WDF to start the device in the fully-on power state.
DoTraceMessage(MYDRIVER_ALL_INFO, "Tracing Device Entry");
auto* pContext = WdfObjectGet_IndirectDeviceContextWrapper(Device);
pContext->pContext->InitAdapter();
return STATUS_SUCCESS;
}
I make sure WPP Tracing is set to YES in the properties of the project.
The project builds, I go into TraceView and open the IddSampleDriver.PDB file, I set the level to verbose, and check all of the flags. I verified that it has the trace stuff it needs. Since if I open the IddSampleApp.PDB file, it fails.
I install the driver after enabling TestSigning and installing with pnputil -a ./x64/Debug/IddSampleDriver/IddSampleDriver.inf, run the sample app, the driver spins up 3 virtual monitors in the Display Settings. I then exit the app, and the monitors disappear. Everything seems to be functional. The problem is there is no traces in TraceView.
I have tried using tracelog, following this. Still nothing.
I have tried using logman, following this. Still nothing.
I am at my wits end. I spent all last week on this, Trying every possible avenue to get my trace messages to appear.
Either I followed every one of these instructions with no success. Either I somehow messed up every single one of them, or I am missing something else that I need to do in order to view these traces.
Additional Info:
Trace.h was left untouched
Targeting x64, Debug. Running on build machine. Win10.
CTL file I used:
b254994f-46e6-4718-80a0-0a3aa50d6ce4 MyDriver1TraceGuid
Basic process I used (tracelog as example):
tracepdb -f .\x64\Debug\IddSampleDriver.pdb
tracelog -start TestTraceIDD -guid .\guid.ctl -f testTrace.etl -flag 0xff
pnputil -a .\x64\Debug\IddSampleDriver\IddSampleDriver.inf #install driver
.\x64\Debug\IddSampleApp.exe #create software device and attach driver to it
<exit app>
tracelog -stop TestTraceIDD
tracefmt.exe .\testTrace.etl -p . -o test.out```
pnputil -d oem20.inf -f #uninstall driver
Solved my problem. I wasnt actually installing my driver, since it was still installed from the first time I installed it, so it was always using that driver instead of my new one with WPP enabled. I was installing and uninstalling the driver with pnputil.
I was doing pnputil -d oem20.inf -f for example to uninstall the driver. This is BAD. I have learned now that force deleting a driver does nothing. The reason I was force deleting was because it wouldnt delete when i still had a device, even though i would exit the sample app.
So what you have to do in order to properly delete the driver is enumerate the devices with pnputil, remove the ones that use your driver, then delete the driver. This allows a proper fresh driver installation.

Oracle SQL developer connect issue [duplicate]

I'm accessing an Oracle Database from a java application, when I run my application I get the following error:
java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-01882: timezone region not found
You may also try to check the version of the Oracle jdbc driver and Oracle database. Just today I had this issue when using ojdbc6.jar (version 11.2.0.3.0) to connect to an Oracle 9.2.0.4.0 server. Replacing it with ojdbc6.jar version 11.1.0.7.0 solved the issue.
I also managed to make ojdbc6.jar version 11.2.0.3.0 connect without error, by adding oracle.jdbc.timezoneAsRegion=false in file oracle/jdbc/defaultConnectionProperties.properties (inside the jar). Found this solution here (broken link)
Then, one can add -Doracle.jdbc.timezoneAsRegion=false to the command line, or AddVMOption -Doracle.jdbc.timezoneAsRegion=false in config files that use this notation.
You can also do this programmatically, e.g. with System.setProperty.
In some cases you can add the environment variable on a per-connection basis if that's allowed (SQL Developer allows this in the "Advanced" connection properties; I verified it to work when connecting to a database that doesn't have the problem and using a database link to a database which has).
In a plain a SQL-Developer installation under Windows go to directory
C:\Program Files\sqldeveloper\sqldeveloper\bin
and add
AddVMOption -Duser.timezone=CET
to file sqldeveloper.conf.
Error I got :
Error from db_connection.java -->> java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-01882: timezone region not found
ORA-00604: error occurred at recursive SQL level 1ORA-01882: timezone region not found
Prev code:
public Connection getOracle() throws Exception {
Connection conn = null;
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:#127.0.0.1:1521:tap", "username", "pw");
return conn;
}
new Code:
public Connection getOracle() throws Exception {
TimeZone timeZone = TimeZone.getTimeZone("Asia/Kolkata");
TimeZone.setDefault(timeZone);
Connection conn = null;
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:#127.0.0.1:1521:tap", "username", "pw");
return conn;
}
now it is working!!
Update the file oracle/jdbc/defaultConnectionProperties.properties in whatever version of the library (i.e. inside your jar) you are using to contain the line below:
oracle.jdbc.timezoneAsRegion=false
What happens is, that the JDBC client sends the timezone ID to the Server. The server needs to know that zone. You can check with
SELECT DISTINCT tzname FROM V$TIMEZONE_NAMES where tzname like 'Etc%';
I have some db servers which know about 'Etc/UTC' and 'UTC' (tzfile version 18) but others only know 'UTC' (tz version 11).
SELECT FILENAME,VERSION from V$TIMEZONE_FILE;
There is also different behavior on the JDBC client side. Starting with 11.2 the driver will sent the zone IDs if it is "known" to Oracle, whereas before it sent the time offset. The problem with this "sending of known IDs" is, that the client does not check what timezone version/content is present on the server but has its own list.
This is explained in Oracle Support Article [ID 1068063.1].
It seems it also depends on the Client OS, it was more likely that Etc/UTC fails with Ubuntu than RHEL or Windows. I guess this is due to some normalization but I haven't figured out what exactly.
in eclipse go run - > run configuration
in there go to JRE tab in right side panels
in VM Arguments section paste this
-Duser.timezone=GMT
then Apply - > Run
I had this problem when running automated tests from a continuous integration server. I tried adding the VM argument "-Duser.timezone=GMT" to the build parameters, but that didn't solve the problem. However, adding the environment variable "TZ=GMT" did fix it for me.
I ran into this problem with Tomcat. Setting the following in $CATALINA_BASE/bin/setenv.sh solved the issue:
JAVA_OPTS=-Doracle.jdbc.timezoneAsRegion=false
I'm sure that using one of the Java parameter suggestions from the other answers would work in the same way.
ERROR :
ORA-00604: error occurred at recursive SQL level 1 ORA-01882: timezone region not found
Solution:
CIM setup in Centos.
/opt/oracle/product/ATG/ATG11.2/home/bin/dynamoEnv.sh
Add this java arguments:
JAVA_ARGS="${JAVA_ARGS} -Duser.timezone=EDT"
In Netbeans,
Right-click your project -> Properties
Go to Run (under Categories)
Enter -Duser.timezone=UTC or -Duser.timezone=GMT under VM Options.
Click Ok, then re-run your program.
Note: You can as well set to other timestones besides UTC & GMT.
If this problem is in JDeveloper:
Change the project properties for both the model and the view project -> run/debug -> default profile -> edit
add the following run option:
-Duser.timezone=Asia/Calcutta
Make sure that the above time zone value is fetched from your database as follows:
select TZNAME from V$TIMEZONE_NAMES;
Along with that you'd want to check the time zone settings in your jdev.conf as well as in the JDeveloper -> Application Menu -> Default Project Propertes -> Run/Debug -> Default Profile -> Run Options.
I also same faced similar issue.
Environment:
Linux, hibernate project, ojdbc6 driver while querying oracle 11g database.
Resolution
TZ parameter was not set in linux machine, that basically tell oracle about the timezone.
So, After adding export statment "export TZ=UTC" at time of application start solved my problem.
UTC--> Change accorind to your timezone.
I had the same problem when trying to make a connection on OBIEE to Oracle db.
I changed my Windows timezone from (GMT+01:00) West Central Africa to (GMT+01:00) Brussels, Copenhagen, Madrid, Paris. Then I rebooted my computer and it worked just fine.
Seems like Oracle was not able to recognize the west central Africa timezone.
This issue happens as the code which is trying to connect to db, has a timezone which is not in db.
It can also be resolved by setting the time zone as below or any valid time zone available in oracle db.
valid time zone which can be found select * from v$version;
System.setProperty("user.timezone", "America/New_York");
TimeZone.setDefault(null);
I too had the same problem when i tried to create connection in JDeveloper. Our server located in different timezone and hence it raised the below errors as:
ORA-00604: error occurred at recursive SQL level 1
ORA-01882: timezone region not found
I referred many forums which asked to include timezone in the Java Options(Run/Debug/Profile) of Project properties and Default Project properties as -Duser.timezone="+02:00" bBut it didn't work for me. Finally the following solution worked for me.
Add the following line to the JDeveloper's configuration file (jdev.conf).
AddVMOption -Duser.timezone=UTC+02:00
The file is located in "<oracle installation root>\Middleware\jdeveloper\jdev\bin\jdev.conf".
In my case I could get the query working by changing "TZR" with "TZD"..
String query = "select * from table1 to_timestamp_tz(origintime,'dd-mm-yyyy hh24:mi:ss TZD') between ? and ?";
I was able to solve the same issue by setting the timezone in my linux system (Centos6.5).
Reposting from
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html
set timezone in /etc/sysconfig/clock e.g. set to ZONE="America/Los_Angeles"
sudo ln -sf /usr/share/zoneinfo/America/Phoenix /etc/localtime
To figure out the timezone value try to
ls /usr/share/zoneinfo
and look for the file that represents your timezone.
Once you've set these reboot the machine and try again.
Facing the same issue using Eclipse and a distant Oracle Database, changing my system time zone to match the time zone of the database server fixed the problem.
Re-start the machine after changing system time zone.
I hope this can help someone
java.sql.SQLException: ORA-00604: error occurred at recursive SQL
level 1 ORA-01882: timezone region not found
For this type of error, just change your system time to your country's standard GMT format
e.g. Indian time zone is chennai,kolkata.
Happens when you use the wrong version of OJDBC jar.
You need to use
11.2.0.4
For my case, i set the timezone at my OS level (ubuntu) with this command.
timedatectl set-timezone {timezone}
For example,
timedatectl set-timezone Africa/Kampala
This might be a bit late but It may help someone.
I encountered this issue while working on spring-boot application and failed to connect to the Oracle DB.
Error:
java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-01882: timezone region not found
SELECT DBTIMEZONE FROM dual; -- This return: +00:00
timedatectl #The OS on the other hand returned correct time and timezone
Since I am not a system admin and not allowed to change system config, I had to apply a workaround in the codes.
spring.datasource.hikari.data-source-properties.oracle.jdbc.timezoneAsRegion=false
#Added the above into the application property file
The working solution came from the below link
Working solution URL
Edit
After the DBA patched the oracle with the missing timezone patches, The above (...timezoneAsRegion=false) was no longer needed.
For Spring-Boot Application - // add below two lines
#SpringBootApplication
public class Application {
public static void main(String[] args) {
// add below two lines
System.out.println("Setting the timezone"+TimeZone.getTimeZone("GMT+9:00").getID());
TimeZone.setDefault(TimeZone.getTimeZone("GMT+9:00"));
SpringApplication.run(Application.class, args);
}
}

Intermittent 500 internal server error in images after adding isolation_level to a flask-sqlalchemy app on apache mod_wsgi server

I am using Apache mod_wsgi in a flask-sqlalchemy, marshamllow application, connecting to a remote ms sql database using pyodbc, recently I was asked to add isolation_level 'SNAPSHOT' and I did that using apply_driver_hacks
class SQLiteAlchemy(SQLAlchemy):
def apply_driver_hacks(self, app, info, options):
options.update({
'isolation_level': 'SNAPSHOT',
})
super(SQLiteAlchemy, self).apply_driver_hacks(app, info, options)
the project is built to access image blob data from a ms sql server and display on a webpage, soon after adding the isolation level I see internal error generated for every few images, doing a ctrl+f5 displays the image but then there are other images not being displayed and this is in the error log
mod_wsgi (pid=10694): Exception occurred processing WSGI script
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Transaction failed in database 'testdb' because the statement was run under snapshot isolation but the transaction did not start in snapshot isolation. You cannot change the isolation level of the transaction to snapshot after the transaction has started unless the transaction was originally started under snapshot isolation level. (3951) (SQLExecDirectW)")
edited to add code below:
how would I do that with flask-sqlalchmey when not using create-engine
my app.py file
app = Flask(__name__)
app.config.from_object('config.ProductionConfig')
db.init_app(app)
ma.init_app(app)
my model.py file
class SQLiteAlchemy(SQLAlchemy):
def apply_driver_hacks(self, app, info, options):
options.update({
'isolation_level': 'SNAPSHOT',
})
super(SQLiteAlchemy, self).apply_driver_hacks(app, info, options)
# To be initialized with the Flask app object in app.py.
db = SQLiteAlchemy()
ma = Marshmallow()
At Engine Level
If you were using the declaritive implementation you would have access to the create engine function (and the scoped session one).
But assuming you're using the Flask-SQLAlchemy implementation, this just calls sqlalchemy.create_engine under the hood (on this line).
Might be a hack for the latter, as there doesn't seem to be a way to pass engine related options in; they are defined specifically a few lines up at #558:
options = {'convert_unicode': True}
At Session Level
This looks like it could be slightly easier, because you can pass session options when you initialise SQLAlchemy: see this line. The create_scoped_session method expects a dictionary which can be passed to the __init__ method as session_options.
So when you initialise the library you could try something like:
db = SQLiteAlchemy(session_options={'isolation_level': 'SNAPSHOT'})

How to connect an Oracle Database to Mathematica?

I am trying to connect an Oracle database to Mathematica 8. Another question already says how it can be done in for a MySQL database but it does not work for me:
Needs["DatabaseLink"] AND conn = OpenSQLConnection[JDBC["MySQL(Connector/J)",
"yourserver/yourdatabase"], "Username" -> "yourusername", "Password" -> "yourpassword"]
The following information is available for me on my desktop:
filepath = "C:\oracle\ora92\network\ADMIN\tnsnames.ora"; HOST; PORT; username; password;
conn = OpenSQLConnection[JDBC["MySQL(Connector/J)", HOST], "Username" -> username, "Password" -> password]
Error message: JDBC::error:
Communications link failure The last packet sent successfully to the server was 0 milliseconds ago.
The driver has not received any packets from the server. >>
Does anyone know how I can connect or continue?
Mathematica 8 does not come pre-equipped with an Oracle driver, a fact that can be verified by evaluating these expressions:
Needs["DatabaseLink`"]
JDBCDriverNames[]
(*
Out[2]= {Microsoft Access(ODBC),hsqldb,HSQL(Memory),HSQL(Server),
HSQL(Server+TLS),HSQL(Standalone),HSQL(Webserver),HSQL(Webserver+TLS),
jtds_sqlserver,jtds_sybase,mysql,MySQL(Connector/J),ODBC(DSN),odbc,
PostgreSQL,Microsoft SQL Server(jTDS),Sybase(jTDS),HSQL 2.0.1}
*)
We will have to follow the instructions in the Mathematica documentation that describes how to install a new JDBC driver.
First, we will have to create a new resource directory in which to place the necessary JDBC driver JAR file:
$jarDirectory =
CreateDirectory #
FileNameJoin #
{$UserBaseDirectory, "Applications", "Oracle", "Java"}
Next, we must select a JDBC driver to use. Visit the relevant Oracle page to find the correct JDBC driver for your database.
Chose a driver version that is compatible with Java 6, the version that Mathematica 8 uses internally. For this example, I chose to use the Oracle 11.2.0.2.0 driver for Java 6. Download the file and then move it into the resource directory just created:
SystemOpen[$jarDirectory]
Next, we will create a JDBC driver configuration file so that the new driver is registered with Mathematica:
$configDirectory =
CreateDirectory #
FileNameJoin #
{$UserBaseDirectory, "Applications", "Oracle", "DatabaseResources"}
Export[
FileNameJoin # {$configDirectory, "Oracle.m"}
, JDBCDriver[
"Name" -> "Oracle"
, "Driver" -> "oracle.jdbc.driver.OracleDriver"
, "Protocol" -> "jdbc:oracle:thin:#"
, "Version" -> 1
]
, "Text"
]
The driver is now installed:
JDBCDriverNames[]
(*
Out[9]= {Oracle,Microsoft Access(ODBC),hsqldb,HSQL(Memory),HSQL(Server),
HSQL(Server+TLS),HSQL(Standalone),HSQL(Webserver),HSQL(Webserver+TLS),
jtds_sqlserver,jtds_sybase,mysql,MySQL(Connector/J),ODBC(DSN),odbc,
PostgreSQL,Microsoft SQL Server(jTDS),Sybase(jTDS),HSQL 2.0.1}
*)
If the fates are smiling, we can now establish a connection and execute an SQL query:
$connection =
OpenSQLConnection[
JDBC["Oracle", "myserver:1521:mysid"]
, "Username" -> "scott"
, "Password" -> "tiger"
]
SQLExecute[$connection, "SELECT 'success!' FROM DUAL"]
... where myserver is the database server name, 1521 is the listener port number and mysid is the Oracle System ID (SID).
Oracle JDBC URLs come in many forms. For details, take a look at the Oracle FAQ.
I suspect that you are using the wrong JDBC driver - you should be using the Oracle JDBC driver, rather than MySQL one. When I was using DatabaseLink to connect to an Oracle database, I used this command:
OpenSQLConnection[
JDBC[
"oracle.jdbc.driver.OracleDriver",
"jdbc:oracle:thin:#server:port:dbname"
],
"Name" -> "dbname",
"Username" -> "YourUserName",
"Password" -> "YourPassword"
]
You should make sure to put the proper Oracle JDBC driver (corresponding to your Oracle db version) into a place where Mathematica can find it. This procedure is described in the documentation for the DatabaseLink, section JDBC Connections. You can test which JDBC drivers are visible to Mathematica by executing JDBCDrivers[]. Make sure that you install and use the correct driver corresponding to your DB version, b.t.w. - incorrect driver versions may result in very nasty and non-obvious bugs (this is unrelated to Mathematica).
My guess would be that you shouldn't use MySQL JBDC connections for Oracle. Although it is for Mathematica 5.2, here is an article that you perhaps can use as something to go from.
I've barely used Mathematica, and certainly not with a database, but from that page, it looks like you can do this:
OpenSQLConnection[JDBC["oracle","server.business.com:1999"],
Username -> "you"]
Whilst the answer from WReach above is correct it may also be helpful to know that there are 2 additional lines that are useful - namely to make sure Jlink is loaded and the Java ClassPath is correct and pointing to your oracle jdbc6.jar file.
Needs["JLink`"]
AddToClassPath[
FileNameJoin[{$UserBaseDirectory, "Applications", "Oracle",
"Java"}]];
or if using the answer verbatim just
Needs["JLink`"]
AddToClassPath[$jarDirectory];