ORA-20987: APEX – Schema is restricted – Contact your application administrator

I reinstalled Oracle database 19c & lost the APEX setup I had. I installed and configured APEX with ORDS and was online quickly and wanted to add the additional sample schemas, as this time I “was” “SERIOUS” about learning APEX ;)

After setting up the additional sample schemas, I noticed that the new schemas were not available to add to APEX workspaces! Sample schemas those were installed as part of the DBCA were the only ones available for APEX.

Soon, I realized that it was NOT a very stupid silly situation. There were hardly many articles explaining how to overcome this issue and the closest ones were not on Oracle forums as usual, instead on stackoverflow!

Anyway, I stumbled upon a question about APEX 4 and there was one answer dealing with APEX 5, that is still effective on APEX 23.2. Let’s quickly have a look at it.

Find the schemas that are restricted for APEX. Connect as SYS or SYSTEM

ALTER SESSION SET CONTAINER="ORCL"; --your PDB on which the APEX is installed your sample schemas reside
/
SELECT * FROM APEX_230200.wwv_flow_restricted_schemas;
/

The above should provide you a list of schemas that are restricted. “OE” and other sample schemas that you have installed once after setting up the database must be listed in this listing. Now proceed to derestrict the schema for APEX. We will use the sample schema “OE” for this exercise.

EXEC APEX_INSTANCE_ADMIN.UNRESTRICT_SCHEMA('OE');
/

EXEC APEX_INSTANCE_ADMIN.ADD_SCHEMA('YOUR_WORKSPACE_NAME', 'OE');
/
-- Don't forget to commit!
commit;
/

That’s all. Once logged in, APEX will show the schema “OE” or all other schemas you have added following the above method under the targeted workspace.

DBT-50000 Unable to check for available memory

You may run into this error while trying to setup a new database using Oracle 19c DBCA immediately after “software only” installation. The version of software that is available to download from Oracle repository is age old (19.3.0.0 for Windows) & if you are very attentive, notice that the installation process clearly warns about uncertified OS, while the software being installed on latest versions of Windows 11 / or other.

While this doesn’t have anything to do with the “Disabled Admin Shares”, identified as a bug & has a solution.

Open an elevated command prompt, switch to Oracle Home bin folder. and execute the DBCA

dbca.bat -J-Doracle.assistants.dbca.validate.ConfigurationParams=false

You should able to configure the new database without any additional issues this time.

ORA-12518, TNS:listener could not hand off client connection

I recently had to reinstall the 19c database and chose not to configure a new listener since I already had an 11g listener set up. Everything was fine until I attempted to set up APEX again. The APEX installation went well, but when I tried to set up ORDS, I began encountering the following errors..

Connecting to database user: system url: jdbc:oracle:thin:@//localhost:1521/orcl
Failed to connect to user: system url: jdbc:oracle:thin:@//localhost:1521/orcl
Listener refused the connection with the following error:
ORA-12518, TNS:listener could not hand off client connection
  (CONNECTION_ID=GUdr3KiAROGLcH8vxlpaMg==)
java.sql.SQLException: Listener refused the connection with the following error:
ORA-12518, TNS:listener could not hand off client connection
  (CONNECTION_ID=GUdr3KiAROGLcH8vxlpaMg==)

The situation seemed dire. Oracle support articles primarily addressed process deficiencies and the reconfiguration of 11g listeners for 19c database services, but these methods were ineffective for me this time. After some research, I stumbled upon a post detailing Oracle Net Services versions 9.2.0.5 to 10.2.0.1, notorious for ORA-12518 errors.

Consequently, I eliminated all 19c references from the 11g listener services and established a new 19c listener service. That turned out to be the solution. It appears that the jdbc thin clients utilized by the latest ORDS versions are incompatible with 11g net services, according to my tests. If this resolves your issue, please inform us in the comments!

(This post was rewritten using #Microsoft #Copilot preview)

Install & use Windows 11 without Microsoft account

A day back Elon Musk has complained about Microsoft being petty about forcing users to use Microsoft accounts to setup a new PC. Well, “you really don’t have to” is the shortest answer. So let us see how to setup Windows11 without Microsoft account.

Once the installation completed, Windows will start setting up the PC, collecting information about the geographical location, keyboard and layout etc. Once after renaming your PC, the box will restart.

Now you can setup the PC without a Microsoft account by following the instructions below. Select “Set up for work or school” from the given options.

Click “Sign-in option” that Microsoft tries to make look less significant & that’s what let you create a local account instead of using Microsoft account.

Select “Domain join instead”

Enter your username

Setup your password

Confirm the password in the next screen.

Setup 3 different security questions and answers for situations when you forget your password in next three screens.

Basically you don’t have to agree to any of the options proved in the “Choose privacy settings for your device” screen. Toggle all of them to No if you prefer. I keep location yes (usually)

That’s all folks. Your PC will take few minutes to setup & soon you should using your PC without a Microsoft account.

The above instructions were tested on Windows 11 23H2 (OS Build 22631.3227)

Yes, I am tagging #ElonMusk

Oracle Applications (EBS R12) Site level Tax Profile API

No, there are no documented APIs are available for this requirement, or that is what claimed by Oracle community MOSC support on different discussions. So what happens when the country where you live and work decides to implement Tax (example, Middle East countries) and you were using Oracle applications(EBS) over a decade already without Tax setup? Are you going to open up each and every other customer/supplier account and setup the Tax profile? We are using Multi-organization structure and we have 8 companies under the same business group. We’ve 13,000 unique parties in our database and most of them are linked to all these organizations! It didn’t look good for us, I am sure it doesn’t look good for anyone else either!

Then I came across a poorly constructed sample for an API “zx_registrations_pkg.insert_row” that is “not well documented” by Oracle. This means, Oracle doesn’t categorize this API as public & they will not support the customer if something goes wrong while using this API. Hence, make sure that you are going to use an API that could turn stuffs into a nightmare.

Let’s see how to use this API now. Some technical details for better understanding where to look for some mandatory elements. Every time a new site created for customer or supplier, the TAX profile table (ZX_PARTY_TAX_PROFILE) is inserted with a new row, bearing the PARTY_ID column populated with newly created Site’s id (PARTY_SITE_ID) value. Given example below, I am setting up Tax profiles for customers and suppliers that were created for a new organization bearing organization id “285”

For the purpose, I created a new view comprise of both customer and supplier sites details. Please judge me because I am using “A” and “B” for aliases ;)

CREATE VIEW XXKCC_VAT_TABLE_V AS SELECT
hcas.org_id, ac.customer_id party_id, ac.customer_number party_number, ac.customer_name party_name,ac.customer_type party_type, hcas.party_site_id, 'CUSTOMER' as party_classification
FROM
hz_cust_acct_sites_all hcas
inner join ar_customers ac on ac.customer_id= hcas.cust_account_id
where
1=1
and hcas.status='A'
AND ac.status ='A'
AND NVL(ac.customer_type,'R') ='R'--Account type is empty for maximum bahrain customers
AND hcas.org_id=285
UNION ALL
select b.org_id, b.vendor_id party_id, A.segment1 party_number, a.vendor_name,NULL party_type, b.party_site_id, 'SUPPLIER' as party_classification
from AP_SUPPLIERS A
inner join AP_SUPPLIER_SITES_ALL B ON B.VENDOR_ID = A.VENDOR_ID
where B.ORG_ID = 285
/

I am using two different staging tables with VAT/TRN numbers & aliased as “B” in the following PL/SQL blocks. I executed the same script twice, once for customer and other time for supplier. Please note, I have hard coded many parameters, including TAX_AUTHORITY_ID. Make sure that you change such information to suit your environment. Although, we applied this solution to PRODUCTION, I would recommend everyone to practice caution, make backups.

DECLARE
CURSOR CUSTOMER_RECORD IS
SELECT B.VAT_TRN_NUMBER vat_registration_num,'VAT' REGISTRATION_TYPE_CODE, 'UP' ROUNDING_RULE_CODE,'TAX BH JURISDICTION' TAX_JURISDICTION_CODE,
'REGISTERED' REGISTRATION_STATUS_CODE, 'TAX BAHRAIN' TAX, 'TAX REGIME BAHRAIN' TAX_REGIME_CODE,5379228 TAX_AUTHORITY_ID,'N' SELF_ASSESS_FLAG,'IMPLICIT' REGISTRATION_SOURCE_CODE,
'N' INCLUSIVE_TAX_FLAG,'USER_DEFINED' RECORD_TYPE_CODE,
A.* FROM XXKCC_VAT_TABLE_V A
INNER JOIN XX_BAH_CUSTOMER_T B ON B.ERP_CUSTOMER_ID = A.PARTY_ID
WHERE
1=1
AND A.PARTY_CLASSIFICATION='CUSTOMER'
AND B.VAT_TRN_NUMBER IS NOT NULL;
--AND A.PARTY_SITE_ID=3702712;
g_return_status varchar2(1);
l_party_tax_profile_id NUMBER;
BEGIN
for i in CUSTOMER_RECORD loop
BEGIN
Select PARTY_TAX_PROFILE_ID into l_party_tax_profile_id from
ZX_PARTY_TAX_PROFILE
where party_id = i.party_site_id;
EXCEPTION
when no_data_found then
l_party_tax_profile_id:=NULL;
END;
IF l_party_tax_profile_id IS NOT NULL THEN
zx_registrations_pkg.insert_row(
p_request_id => NULL
,p_attribute1 => NULL
,p_attribute2 => NULL
,p_attribute3 => NULL
,p_attribute4 => NULL
,p_attribute5 => NULL
,p_attribute6 => NULL
,p_rounding_rule_code => i.ROUNDING_RULE_CODE
,p_validation_rule => NULL
,p_tax_jurisdiction_code => i.TAX_JURISDICTION_CODE
,p_self_assess_flag => i.SELF_ASSESS_FLAG
,p_registration_status_code => i.REGISTRATION_STATUS_CODE
,p_registration_source_code => i.REGISTRATION_SOURCE_CODE
,p_registration_reason_code => NULL
,p_tax => i.TAX
,p_tax_regime_code => i.TAX_REGIME_CODE
,p_inclusive_tax_flag => i.INCLUSIVE_TAX_FLAG
,p_effective_from => SYSDATE
,p_effective_to => NULL
,p_rep_party_tax_name => NULL
,p_default_registration_flag => NULL
,p_bank_account_num => NULL
,p_record_type_code => i.RECORD_TYPE_CODE
,p_legal_location_id => NULL
,p_tax_authority_id => i.TAX_AUTHORITY_ID
,p_rep_tax_authority_id => NULL
,p_coll_tax_authority_id => NULL
,p_registration_type_code => i.REGISTRATION_TYPE_CODE
,p_registration_number => i.vat_registration_num
,p_party_tax_profile_id => l_party_tax_profile_id
,p_legal_registration_id => NULL
,p_bank_id => NULL
,p_bank_branch_id => NULL
,p_account_site_id => NULL
,p_attribute14 => NULL
,p_attribute15 => NULL
,p_attribute_category => NULL
,p_program_login_id => NULL
,p_account_id => NULL
,p_tax_classification_code => NULL
,p_attribute7 => NULL
,p_attribute8 => NULL
,p_attribute9 => NULL
,p_attribute10 => NULL
,p_attribute11 => NULL
,p_attribute12 => NULL
,p_attribute13 => NULL
,x_return_status => g_return_status
);
END IF;
DBMS_OUTPUT.PUT_LINE(i.PARTY_NUMBER||', '||i.party_name||' Process status : '||g_return_status);
--"S" for success, any other means trouble ;)
END loop;
--COMMIT;
END;
/

That’s all folks. Have questions? Use the comments section to let me know.

Purger | File shredder project for Windows

One of the major benefits of getting exposed to Linux was coming across some fabulous tools for managing and manipulating files. Let it be a simple utility that could replace strings within hundreds of files within a path or find and delete files matching patterns, age etcetera was out of the box available on most of the Linux distributions. Windows Operating System lacks such tools out of the box & next possibility is to write own scripts, which is not very possible for many users.

“Purger” is a file shredding project that I devised few years ago, while we were still hosting our Oracle 11g R2 version on Windows for multiple custom business applications, that generated multiple log files. Today I am sharing a working version of the software with you!

Download Purger

This software can, recursively scan and list files that match the age specified by the user & delete them from the file system. I’ve a minimalistic help file (PDF) under the help section of the software, please make sure that you will read it before using the software.

I’ve tried my level best to ensure that the software doesn’t give the user surprises. Regardless, observe caution when you are using the same as the software is expected to “delete” or “purge” files from your system permanently. If you are not using the “Send to Recyclebin” option, you might end up using tools like Recuva to recover the files deleted!

Do let me know if you have comments.

Microsoft Exchange | empty ECP OWA pages

Recently we switched to wildcard SSL certificate & our on premise exchange services were configured to use the new certificate from ECP. Then, we upgraded our Antivirus software on the Exchange server and needed a reboot.

Once after the physical reboot, Exchange services completely looked toasted. Although the users were able to logon to OWA, after authentication it was just blank, empty pages. We are using Microsoft Exchange 2013 and a quick search landed us on this page.

As per instructions provided by Microsoft, we found out that the IIS “Exchange Back End” site didn’t have the SSL certificate assigned. Once after assigning the new wildcard certificate, we restarted IIS and all services came online immediately after that.

Oracle 19c | Install sample schemas

Updated on 3rd June 2025

After a fresh installation of Oracle 19c and patch update to 25, I couldn’t get the mksample.sql to work as explained below. The 12th parameter for connect string “localhost:1521/SCT” started throwing many errors like listed below:

SQL*Loader: Release 19.0.0.0.0 - Production on Tue Jun 3 13:47:18 2025
Version 19.25.0.0.0

Copyright (c) 1982, 2024, Oracle and/or its affiliates.  All rights reserved.

SQL*Loader-704: Internal error: ulconnect: OCIServerAttach [0]
ORA-12154: TNS:could not resolve the connect identifier specified

I checked tnsnames.ora and listener.ora files to ensure that the necessary entries were available for the PDB so that I can connect to the PDB directly from .Net applications. I couldn’t figure out what was going wrong, and decided to give it a try by connecting to the the PDB directly and executing the mksample.sql script. This also didn’t work as the script failed to connect to the connection string.

For a curiosity purpose, I decided to enter only the connect string name during the next attempt and the script executed without any troubles. If you are facing the same issue, make sure that the current CMD is completely closed and you will execute the script from a new command window. Let us see how it work.

SCT is my PDB and I am connecting to it as sys & executing the script mksample.sql

That’s it!

End of update 3rd June 2025

Oracle 19c comes with a single sample schema HR. For other sample schemas, we have to download the installation media from github repositories. Today we will see how to install the sample schemas on a pluggable database. We’ll be installing Oracle 19.2 sample schemas and please remember, there are possibilities that the sample schema scripts differ for different releases. you can download the 19.2 sample scripts from here

Now comes the difficult part. Once you extract the archive, it creates a folder “db-sample-schemas-19.2”, unless you modified the extract location. I’ve discussed about this on my other post about the Windows software that I made for replacing strings recursively

Basically, Oracle scripts for sample schemas refer to a path, that has to be changed within all the nested SQL and DAT files being referred by the installer script. This is not going to be an easy task for anyone if manually attempted, prompting me to develop the above discussed small utility. Another approach is to write a batch or Powershell script. I opted the latter. Save the below as PowerShell script. Make sure that you configured the environment to run remote signed scripts.

<# run once for *.sql and again for *.dat #>

$count = 0;
Get-ChildItem 'D:\db-sample-schemas-19.2\*.sql' -Recurse | ForEach {
$count = (get-content $_ | select-string -pattern '__SUB__CWD__').length
if ($count -gt 0) {
Write-Host $_ " has $count matches & a backup file $_.bak will be created."
Copy-Item -Path $_ -Destination $_".bak"
(Get-Content $_ | ForEach { $_ -replace '__SUB__CWD__', 'D:/db-sample-schemas-19.2' }) | Set-Content $_
}
}

The above script should be run twice, to iterate through two different types of files. First time for “.sql” and second time for “.dat”

Once the scripts are modified with the correct path, we can proceed with setting up sample schemas. We will use the script “mksample.sql”. Start sqlplus from the script root, eg: D:\db-sample-schemas-19.2. Don’t forget to alter session to your PDB prior executing the script! Please ensure that you have created a new a tablespace “EXAMPLE” if it doesn’t exist (You can use another existing tablespace for the purpose, however not recommended)

Usually the script completes generating few errors. You can check the log files for detailed information about what went wrong, that are insignificant as long as you are only looking at tables/views and indexes.

Hope this helps!

winreplace | command line utility for string replacement recursively

Few days back I posted couple of articles related to Oracle APEX & realized that my test database doesn’t have sample schemas other than HR. So, I decided to download and setup them. Once after extracting the archives from github for 19c, the installation thrown many errors about SQL files not being found in the path “__SUB__CWD__

So I opened couple of the files and found entries like this

CONNECT system/&&password_system@&&connect_string

SET SHOWMODE OFF

@__SUB__CWD__/human_resources/hr_main.sql &&password_hr &&default_ts &&temp_ts &&password_sys &&logfile_dir &&connect_string

CONNECT system/&&password_system@&&connect_string
SET SHOWMODE OFF

@__SUB__CWD__/order_entry/oe_main.sql &&password_oe &&default_ts &&temp_ts &&password_hr &&password_sys __SUB__CWD__/order_entry/ &&logfile_dir &vrs &&connect_string

CONNECT system/&&password_system@&&connect_string

SET SHOWMODE OFF

@__SUB__CWD__/product_media/pm_main.sql &&password_pm &&default_ts &&temp_ts &&password_oe &&password_sys __SUB__CWD__/product_media/ &&logfile_dir __SUB__CWD__/product_media/ &&connect_string

A quick search landed me on oracle-base article about installing samples schemas. This article explains how to replace “__SUB__CHD__” string with the present working directory (pwd) value. Unfortunately, Windows doesn’t have a built-in tool for such & I decided to make one for myself. “winreplace” is a Windows executable developed using C# (C Sharp). I’ve used Visual Studio 2019 community edition for developing this application. You may use later versions and higher .Net framework versions as it suits your requirements. This utility can iterate through files and sub-folders within a directory and replace strings. I avoided command line arguments as maintaining the position and spaces could be challenging at times. All arguments expected by the application are accepted through individual prompts and they must be entered without quotes. Below code was last modified on 6th January 2024. The latest build insures that ONLY the files modified.

using System;

using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace winreplace
{
class Program
{
static void Main(string[] args)
{
//Console.WriteLine("Hello World!");
//https://learn.microsoft.com/en-us/dotnet/api/system.io.directory.enumeratefiles?view=net-8.0&redirectedfrom=MSDN#overloads
//https://stackoverflow.com/questions/59734757/save-with-different-name-in-c-sharp-form-application

string sourceDirectory = string.Empty;
string fileType = string.Empty;
string searchString = string.Empty;
string replaceString = string.Empty;
string backupFiles = string.Empty;

//Accept user inputs
//We'll not do extensive validations for this release. User have to insure the validity of information passed as inputs
Console.WriteLine(@"winreplace by simpleoracle.com, Version 1.0, December 31, 2023");
Console.WriteLine(@"This utility could be used for replacing specific strings recursively within a given file path. This utility creates a "".bak"" file for each file it iterates through regardless whether a match found or not. Fix expected.");
Console.WriteLine(@"This utility is provided as it is and you are adviced to use the same with caution. Although the software creates a backup for every file it accesses, making additional backups for important files is totally user's responsibility. Simpleoracle.com will not able to fix/repair or recover your files under any circumstances once after they are modified.");
Console.WriteLine("\n");

Console.Write(@"Files Path(eg: D:\My Text Files are here): ");
sourceDirectory = Console.ReadLine();

Console.Write(@"File type(eg: *.txt): ");
fileType = Console.ReadLine();

Console.Write(@"String to search for(eg: domain name): ");
searchString = Console.ReadLine();

Console.Write(@"String to replace with(eg: simpleoracle.com): ");
replaceString = Console.ReadLine();

try
{
var txtFiles = Directory.EnumerateFiles(sourceDirectory, fileType, SearchOption.AllDirectories);
foreach (string currentFile in txtFiles)
{
string fileName = currentFile.Substring(sourceDirectory.Length + 1);
//Directory.Move(currentFile, Path.Combine(archiveDirectory, fileName));
//Comment the below line if you don't want to create backup files.
ReplaceInFile(currentFile, searchString, replaceString);
//Console.WriteLine(fileName);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}

static public void ReplaceInFile(string filePath, string searchText, string replaceText)
{
//We will get the content from the plain text type file.
StreamReader reader = new StreamReader(filePath);
string content = reader.ReadToEnd();
reader.Close();
//Now we will check whether the content read from the file
//has matches for the string that we are searching for.
MatchCollection matches = Regex.Matches(content, searchText);
int count = matches.Count;
//We will attempt to replace the strings only if matches exist
//Each file that is modified will be backed up with an extension ".bak"
if (count > 0)
{
try
{
Console.WriteLine("{0} has {1} Matches. File will be backed up", filePath, count);
File.Copy(filePath, filePath + ".bak", true);
content = Regex.Replace(content, searchText, replaceText);
StreamWriter writer = new StreamWriter(filePath);
writer.Write(content);
writer.Close();
}
catch (Exception e)
{
Console.WriteLine("There was an error. Please check whether the file is read only.");
}
}
}
}
}


You can download a published version from this link. Extract the contents to a single folder, eg: D:\winreplace. This application can work ONLY with plain text files like .txt, .sql, .log and files of same nature. This software cannot be used for Microsoft documents/PDF or documents of such complex architecture. Read more about Microsoft documents/PDF here

Now add this path to PATH environment variable, that will help you to access the executable from any command prompt.

You can call the executable as demonstrated in the image below.

I was pretty happy, being able to fix the sql, dat files as mentioned in the oracle-base article using “my own” utility.

Please note, there are hardly any error handling included with the application. Please ensure to make backups for your important files prior using this utility. I’ve added a no liability clause with the software (not visible with the images above as it was added later)

You must run the executable each time for different types of files. If the application fails, default error messages will be displayed, giving you a hint about what went wrong.

That’s all folks.

Oracle APEX on Apache Tomcat

Referred documents

https://oracle-base.com/articles/misc/oracle-rest-data-services-ords-installation-on-tomcat-windows

Oracle keeps releasing new versions of both APEX and ORDS once in couple of months, if not weeks. Posting a fresh article for each and every other version looks pretty hectic and I have decided to maintain a single post with specific instructions for versions that I tested at lab. Please refer “Install APEX on Windows” for details about installing APEX on Windows.

Assuming the APEX with ORDS installation all good, we will see how to setup ORDS using Apache Tomcat now. Please note, Apache Tomcat 9.x is the latest version supported by ORDS. You can read about the differences between Tomcat 9 and Tomcat 10 here (As on 23rd Dec 2023, Tomcat10 doesn’t work with ORDS)

I suggest going with the Zip package. You can opt for the Windows Service installer, if you are setting APEX for regular development or PRODUCTION usage. Please refer the following link for detailed information about setting up Apache Tomcat on Windows. https://phoenixnap.com/kb/install-tomcat-window

Let’s setup Apache Tomcat for ORDS now, assuming Apache Windows Service is not installed.

I have the Tomcat 9 software extracted to the folder to D:\apache-tomcat. Please make sure that you will setup the server.xml with ports that are freely available on your system prior attempting to start the web server.

The following are the areas you must thoroughly confirm within the server.xml file that is available in “conf” folder.

Let’s quickly make some minor change to web.xml, allowing directory browsing. We’ll change the listing parameter value from “false” to “true”

There are many other changes we must make for a PRODUCTION instance. For the current purpose, this is enough to start with.

Now, we will quickly copy the ORDS and APEX images to Tomcat apps section so that they could be mapped.

  1. Copy “ords.war” from the ORDS installation source to webapps
  2. Copy the “images” folder from APEX installation source & rename it to “i”
  3. Refer the below image for details.

From an elevated command prompt, switch to Apache Tomcat BIN folder. We need to setup some environment variables prior starting Tomcat server.

D:\apache-tomcat\bin>set JAVA_HOME=C:\Java\jdk-17 --JDK path

D:\apache-tomcat\bin>set ORDS_CONFIG=D:\ORDS\config --location that was selected for configuring ORDS, this location has all details for database connection and more.

D:\apache-tomcat\bin>set JAVA_OPTS="-Dconfig.url=%ORDS_CONFIG%" -Xms1024M -Xmx2G --Dconfig.url is the place where Tomcat server looks for ORDS configurations. Finaly Xms and Xmx are the JAVA min and max memory settings. For PRODUCTION, these parameters should be configured precisely to avoid performance bottlenecks.

D:\apache-tomcat\bin>startup --will start the web server.

Let us try to access ORDS now. The below is the landing page, from which you can start SQL Developer Web APEX and ORDS authentication.

You can use “shutdown.bat” to stop the Tomcat server.

If set is expected to be used for longer intervals, we can install Tomcat as Windows Service. Please note the forward slashes “/”. Oracle allows both forward and backward slashes for these kind of settings.

Note the service name “Tomcat9”. You should use the same name, so that the service configuration executable(tomcat9w.exe) can be used for setting up ORDS specifics at post service installation.

Once the service installed, let us quickly move to Tomcat bin folder. Open “tomcat9w.exe”

let’s configure the JAVA options section with the “-Dconfig.url”, pointing to the ORDS config path.

Start the “Apache Tomcat 9.0 tomcat9” Windows service now. Set the service to start manually or automatic based on your requirements. Remember, ORDS will not start if the database instance is not open.