Configure Oracle Reports 12c (12.2.x) for destype=file

Posted by Dirk Nachbar on Friday, September 29, 2017
I currently had in a project a request, that Oracle Reports should be generated with the option destype=file to a specific location on the server which is hosting the Oracle Forms & Reports 12c environment.

Since Oracle Forms & Reports 12c, the so called "File System Access Control" is enabled by default, so any request like http://<server>:<Port_of_ManagedServer_Reports>/reports/rwservlet?report=test.rdf&userid=test/test@db1&destype=file&desformat=pdf&desname=/u00/app/oracle/demo_app/rep_output/test.pdf&server=rep_server1 will fail:

When you check the corresponding log files for your Reports Server you will find following:

cd $DOMAIN_HOME/servers/<ReportsServerName>/logs
vi rwEng-0_diagnostic.log

[2017-09-29T10:27:14.058+02:00] [reports] [INCIDENT_ERROR] [REP-69] [oracle.reports.engine] [tid: 12] [ecid: 0000LvCjcD33n3WjLxjO8A1PnW5h000008,0:1:100000001] [EngineName: rwEng-0] REP-69 : An internal error occurred[[
REP-56133: Access is denied to write to the specified location.

oracle.reports.RWException: IDL:oracle/reports/RWException:1.0
        at oracle.reports.engine.EngineImpl.run(EngineImpl.java:553)
        at oracle.reports.engine.EngineClassPOA._invoke(EngineClassPOA.java:104)
        at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:654)
        at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:205)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1700)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1558)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:940)
        at com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:198)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:712)
        at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.dispatch(SocketOrChannelConnectionImpl.java:471)
        at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.doWork(SocketOrChannelConnectionImpl.java:1230)
        at com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:490)
        at com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:519)

]]
[2017-09-29T10:27:14.058+02:00] [reports] [NOTIFICATION] [] [oracle.reports.engine] [tid: 12] [ecid: 0000LvCjcD33n3WjLxjO8A1PnW5h000008,0:1:100000001] [EngineName: rwEng-0] EngineImpl:run  oracle.reports.RWException: IDL:oracle/reports/RWException:1.0

You simply have to edit your rwserver.conf of your Reports Server and add the required folderAccess option within your engine. The required folderAccess option looks like that:

# Single Target Directory
      <folderAccess>
          <write>Target_Directory</write>
      </folderAccess>

# Multiple Target Directories are separated with semi-colon
      <folderAccess>
          <write>Target_Directory1;Target_Directory2</write>
      </folderAccess>


Example:

cd $DOMAIN_HOME/config/fmwconfig/components/ReportsServerComponent/<ReportsServerName>
vi rwserver.conf

<?xml version = '1.0' encoding = 'ISO-8859-1'?>
<server  
    xmlns="http://xmlns.oracle.com/reports/server"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    >

   <cache class="oracle.reports.cache.RWCache">
      <property name="cacheSize" value="50"/>
      <property name="cacheDir" value="/u00/app/oracle/demo_app/tmp"/>
      <!--property name="maxCacheFileNumber" value="max number of cache files"/-->
   </cache>
   <!--Please do not change the id for reports engine.-->
   <!--The class specifies below is subclass of _EngineClassImplBase and implements EngineInterface.-->
   <engine id="rwEng" class="oracle.reports.engine.EngineImpl" maxEngine="5" minEngine="2" engLife="50" >
      <property name="sourceDir" value="/u00/app/oracle/demo_app/reports"/>
      <property name="tempDir" value="/u00/app/oracle/demo_app/tmp"/>
      <!--property name="keepConnection" value="yes"/-->
      <folderAccess>
          <write>/u00/app/oracle/demo_app/rep_output</write>
      </folderAccess>
   </engine>
   <engine id="rwURLEng" class="oracle.reports.urlengine.URLEngineImpl" maxEngine="1" minEngine="0" engLife="50" />

   <security id="rwJaznSec" class="oracle.reports.server.RWJAZNSecurity"/>
. . .
. . .

After the above changes, you need to stop and start your Reports Server

cd $DOMAIN_HOME/bin
./stopComponent.sh <ReportsServerName>
./startComponent.sh <ReportsServerName> 

# e.g.:
./stopComponent.sh rep_server1
./startComponent.sh rep_server1

Now you can re-run the URL request http://<server>:<Port_of_ManagedServer_Reports>/reports/rwservlet?report=test.rdf&userid=test/test@db1&destype=file&desformat=pdf&desname=/u00/app/oracle/demo_app/rep_output/test.pdf&server=rep_server1 and your PDF named test.pdf will be generated under your target directory you defined in the URL with parameter desname.


Now, lets take the stuff one level upper :-) in some case you will have different sub directories below in which you want to generate your Reports. To list them all by semi-colon separated under the folderAccess parameter is not really my personal goal, so lets try it with wildcard:

# Target Directory with wildcard for sub directories
      <folderAccess>
          <write>Target_Directory/*</write>
      </folderAccess>

In my corresponding rwserver.conf it would look like that:

<?xml version = '1.0' encoding = 'ISO-8859-1'?>
<server  
    xmlns="http://xmlns.oracle.com/reports/server"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    >

   <cache class="oracle.reports.cache.RWCache">
      <property name="cacheSize" value="50"/>
      <property name="cacheDir" value="/u00/app/oracle/demo_app/tmp"/>
      <!--property name="maxCacheFileNumber" value="max number of cache files"/-->
   </cache>
   <!--Please do not change the id for reports engine.-->
   <!--The class specifies below is subclass of _EngineClassImplBase and implements EngineInterface.-->
   <engine id="rwEng" class="oracle.reports.engine.EngineImpl" maxEngine="5" minEngine="2" engLife="50" >
      <property name="sourceDir" value="/u00/app/oracle/demo_app/reports"/>
      <property name="tempDir" value="/u00/app/oracle/demo_app/tmp"/>
      <!--property name="keepConnection" value="yes"/-->
      <folderAccess>
          <write>/u00/app/oracle/demo_app/rep_output/*</write>
      </folderAccess>
   </engine>
   <engine id="rwURLEng" class="oracle.reports.urlengine.URLEngineImpl" maxEngine="1" minEngine="0" engLife="50" />

   <security id="rwJaznSec" class="oracle.reports.server.RWJAZNSecurity"/>
. . .
. . .

After the above changes, restart your Reports Server once again in order to catch the changed rwserver.conf changes.

Under the target directory /u00/app/oracle/demo_app/rep_output I have 2 sub directories called out1 and out2. So lets try to set the desname parameter in the URL call to desname=/u00/app/oracle/demo_app/rep_output/out1/test.pdf
The result will be:


:-( but no worries, just download the patch 22334822 https://updates.oracle.com/download/22334822.html. The patch is available for following Releases:

  • Oracle Reports 12.2.1.0.0
  • Oracle Reports 12.2.1.1.0
  • Oracle Reports 12.2.1.2.0


Simply apply this patch to your Oracle Forms & Reports installation:

# Stop your complete Oracle Forms & Reports Environment
# All Reports Servers, Oracle HTTP Server (OHS), Managed Servers, Admin Server and Node Manager

# unzip the patch and navigate to the sub directory 22334822
unzip p22334822_122120_Generic.zip
cd 22334822
$ORACLE_HOME/OPatch/opatch apply
Oracle Interim Patch Installer version 13.9.1.0.0
Copyright (c) 2017, Oracle Corporation.  All rights reserved.


Oracle Home       : /u00/app/oracle/product/fmw-fr-12.2.1.2.0
Central Inventory : /u00/app/oraInventory
   from           : /u00/app/oracle/product/fmw-fr-12.2.1.2.0/oraInst.loc
OPatch version    : 13.9.1.0.0
OUI version       : 13.9.1.0.0
Log file location : /u00/app/oracle/product/fmw-fr-12.2.1.2.0/cfgtoollogs/opatch/opatch2017-09-29_14-50-57PM_1.log

OPatch detects the Middleware Home as "/u00/app/oracle/product/fmw-fr-12.2.1.2.0"

Verifying environment and performing prerequisite checks...
OPatch continues with these patches:   22334822  

Do you want to proceed? [y|n]
y
User Responded with: Y
All checks passed.

Please shutdown Oracle instances running out of this ORACLE_HOME on the local system.
(Oracle Home = '/u00/app/oracle/product/fmw-fr-12.2.1.2.0')

Is the local system ready for patching? [y|n]
y
User Responded with: Y
Backing up files...
Applying interim patch '22334822' to OH '/u00/app/oracle/product/fmw-fr-12.2.1.2.0'

Patching component oracle.reports.core, 12.2.1.2.0...
Patch 22334822 successfully applied.
Log file location: /u00/app/oracle/product/fmw-fr-12.2.1.2.0/cfgtoollogs/opatch/opatch2017-09-29_14-50-57PM_1.log

OPatch succeeded.

# Afterwards validate that the patch is applied
$ORACLE_HOME/OPatch/opatch lsinventory
Oracle Interim Patch Installer version 13.9.1.0.0
Copyright (c) 2017, Oracle Corporation.  All rights reserved.

. . .
. . .

Interim patches (9) :

Patch  22334822     : applied on Fri Sep 29 14:51:09 CEST 2017
Unique Patch ID:  20728353
Patch description:  "One-off"
   Created on 1 Nov 2016, 01:05:08 hrs PST8PDT
   Bugs fixed:
     22334822

. . .
. . .

Now, just startup your complete Oracle Forms & Reports Environment and you can even use the wildcard option with the folderAccess parameter.

In case you are already on Oracle Forms & Reports 12.2.1.3.0, you are lucky the patch 22334822 is already included and you can use directly the wildcard option :-)