Monday, December 12, 2011

PLSQL block for Publication process

If there is any issue entering parameters for Concurrent program or if you want to automate your publishing process, go for following plsql block:

DECLARE
  P_API_VERSION NUMBER;
  P_PUBLICATION_ID NUMBER;
  P_USER_ID NUMBER;
  P_RESP_ID NUMBER;
  P_APPL_ID NUMBER;
  X_RUN_ID NUMBER;
  X_STATUS NUMBER;
BEGIN
  P_API_VERSION := 1.0;
  P_PUBLICATION_ID := 64689;
  P_USER_ID := 1001530;  --EBUSINESS
  P_RESP_ID := 22687;  --Oracle Configurator Administrator
  P_APPL_ID := 708; --Configurator

  CZ_MODELOPERATIONS_PUB.PUBLISH_MODEL(
    P_API_VERSION => P_API_VERSION,
    P_PUBLICATION_ID => P_PUBLICATION_ID,
    P_USER_ID => P_USER_ID,
    P_RESP_ID => P_RESP_ID,
    P_APPL_ID => P_APPL_ID,
    X_RUN_ID => X_RUN_ID,
    X_STATUS => X_STATUS
  );
  DBMS_OUTPUT.PUT_LINE('X_RUN_ID = ' || X_RUN_ID);
  DBMS_OUTPUT.PUT_LINE('X_STATUS = ' || X_STATUS);
END;

Ensure you enable dbms output to check the return status.
Successful submission would return 0 as x_status.
You can also check in Configurator Developer  >  Publication tab for this publication, it should show as Complete.

P.S. All Configurator process APIs are listed in Implementation Guide of Configurator.
Change user_id, resp_id, appl_id as per your requirement.
For errors, refer cz_db_logs table.

Tuesday, December 6, 2011

Query to extract Oracle Configurator CX rule information


We can use following query to find out all the CX rules in the Configurator model. The query will display the information for the rules like rule_name, java class associated with it, event name, event scope, and oncommand event name.

SELECT DISTINCT RU.RULE_ID, 
  RU.NAME, 
  (SELECT NAME FROM CZ_SIGNATURES WHERE SIGNATURE_ID=EN.ARGUMENT_SIGNATURE_ID) AS EVENTNAME, 
  CLASS_NAME, 
  DECODE(EN.EVENT_EXECUTION_SCOPE, 1, 'Global', 2, 'Base Node SubTree', 4, 'Base Node', 'Unknown') AS SCOPE, 
  EN.DATA_VALUE oncommandEventName
FROM CZ_RULES RU, 
  CZ_EXPRESSION_NODES EN
WHERE DEVL_PROJECT_ID IN (131343) --for given devl_project_id
  AND RU.RULE_ID=EN.RULE_ID
  AND RU.RULE_TYPE=300 --for CX rules
  AND EN.ARGUMENT_SIGNATURE_ID IS NOT NULL --with valid event
  AND RU.DELETED_FLAG=0 --ignore deleted nodes
  AND EN.DELETED_FLAG=0
  AND EN.EXPR_PARENT_ID IS NULL --definition is only on parent node of expression tree
;

This query is useful at times to find out all CX rules with base node subtree event scope which may usually cause performance issue if its unwanted. You can always add other parameters/clauses to filter information as per your need.

Sunday, November 20, 2011

Oracle apps R12 - Compiling JSP with custom classpath

We all know that to compile JSP manually on the Oracle Application R12 instance, we need to run the file $FND_TOP/patch/115/bin/ojspCompile.pl.

Its help is as follows:

syntax: ./ojspCompile.pl COMMAND {ARGS}
COMMAND --compile               update dependency, compile delta
        --create                rebuild entire dependency file
        -delta.out       update dependency, list delta to file
        -dep.out      update dependency, output heirarchy to file

ARGS    -s      matching condition for JSPs filenames
        -p      number of parallel compilations
        -log     to override logfile from ojspCompile.conf
You are
recommended to set the log file location
 outside of any network file system shared (NFS) area/drive.
        -conf    to override ojspCompile.conf
        --retry         retry previously failed compilation attempts
        --flush         forces recompilation of all parent JSPs
        --quiet         do not provide an actively running progress meter
        --fast          instantly fail jsps that are *possibly* invalid

example1: ojspCompile.pl --compile -s 'jtf%' -p 20 --retry
example2: ojspCompile.pl --compile -s 'jtflogin.jsp,jtfavald.jsp' --flush
example3: ojspCompile.pl --compile --fast --quiet

If your JSP uses custom classes, then compiling jsp manually can fail if proper classpath is not set. Yes, even though if you have setup the classpath correctly in orion-application.xml, it will fail because this jsp compile utility does not read orion-application.xml classpath.

So, the problem is to identify where to set the classpath so that above utility can pick it up. After several search and looking into code, I found following:

By default, the jsp compiler script uses following configuration file
$INST_TOP/appl/admin/ojspCompile.conf
This conf file has a classpath field in it which is usually pointed to file
$INST_TOP/appl/admin/ojspCompile.properties
This property file lists the classpath used for JSP compilation.

So if your classes are not listed in this file, your jsps will not compile by ojspCompile.

Ofcourse, you can always set the "main_mode" to "recompile" in orion-web.xml, but that for production you do not want to change it and compile the JSP on file deployment.

References:

  1. 458338.1  How to Enable Automatic Compilation of JSP pages in R12 Environment
  2. 433386.1  JSP Pages Hanging in R12 After Removing Cached Class Files in _pages
  3. 783094.1  Compile jsp files at Application R12 at Windows

Wednesday, November 2, 2011

OC4j Configuration


Oracle application R12 release uses OC4J and during implementation, many would need to modify oc4j configuration for easier/faster development.

I found following links to be useful while changing OC4J configuration for development mode.

OC4J Web Application Redeployment and Class Reloading Features

Element Descriptions for global-web-application.xml and orion-web.xml

Key OC4J Flags for Development

Friday, October 21, 2011

Work-Offline Firefox plugin

As I was going on vacation where there is a limited internet connectivity, I thought it would be great if I could get read some of the webpages offline. But I did not want to save the pages on local manually. I found a good Firefox plugin for it - work offline.

https://addons.mozilla.org/en-US/firefox/addon/work-offline/

Its really useful - when in offline mode, it serves the page if its available in its cache - similar to what is offered by IE's Work Offline feature.
So good for the Firefox lovers.

Friday, October 14, 2011

Compressing and Decompressing String in Java using GZIP streams

Following code can be used to compress or decompress any data in Java using the GZIP streams - java's built in zip streams.
    public static String compress(String str) throws IOException {
        if (str == null || str.length() == 0) {
            return str;
        }
        System.out.println("String length : " + str.length());
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(out);
        gzip.write(str.getBytes());
        gzip.close();
        String outStr = out.toString("ISO-8859-1");
        System.out.println("Output String lenght : " + outStr.length());
        return outStr;
     }
    
    public static String decompress(String str) throws IOException {
        if (str == null || str.length() == 0) {
            return str;
        }
        System.out.println("Input String length : " + str.length());
        GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(str.getBytes("ISO-8859-1")));
        BufferedReader bf = new BufferedReader(new InputStreamReader(gis, "ISO-8859-1"));
        String outStr = "";
        String line;
        while ((line=bf.readLine())!=null) {
          outStr += line;
        }
        System.out.println("Output String lenght : " + outStr.length());
        return outStr;
     }
  
     public static void main(String[] args) throws IOException {
        String filePath = ".\response.txt";
        
        String string = getFileData(filePath);
        System.out.println("after compress:");
        String compressed = compress(string);
        System.out.println(compressed);
        System.out.println("after decompress:");
        String decomp = decompress(compressed);
        System.out.println(decomp);
 
      }
     
     public static String getFileData(String filepath) throws FileNotFoundException,
                                                           IOException {
       BufferedReader bf = new BufferedReader(new FileReader(filepath));
       String data="";
       String line;
       while ((line=bf.readLine())!=null) {
         data += line;
       }
       return data;
     }

Thursday, September 29, 2011

Location of java class file used by Application


Sometimes, while debugging the code, you will be wondering that which class is being picked by Java application from the current Classpath.
Here is some small code snippet to know the location of the class file.
Very simple, it just tries to get the system resource for the class file.

package test.java;

public class ClassSource {

    public static String getClassLocation(String fullQualifiedclassName) throws ClassNotFoundException {
        Class cls = Class.forName(fullQualifiedclassName);
        String classPath = fullQualifiedclassName.replace('.','/').concat(".class");
        if (cls!=null && cls.getClassLoader()!=null) {
            return cls.getClassLoader().getResource(classPath).toString();
        } else {
            return ClassLoader.getSystemResource(classPath).toString();
        }
          
    }
    
    public static void main(String[] args) throws Exception {
        System.out.println("Class Object source : " + getClassLocation("java.lang.Object"));
        System.out.println("Current Class : " + getClassLocation("test.java.ClassSource"));
    }
    
}

Output on my machine:

Class Object source : jar:file:/L:/Program%20Files/Java/jre1.5.0_09/lib/rt.jar!/java/lang/Object.class
Current Class : file:/I:/work/eclipse-workspace/Java-Test/classes/test/java/ClassSource.class

Tuesday, September 27, 2011

Redirecting or Ignoring System.out.println outputs

Recently one of my friend had following requirement. I guess it can be useful to anyone.
In case you want to redirect all the System.out.println() output to some file, you can do using following methods provided by System class.
System.setOut(), System.setIn() and System.setErr()

So, to redirect the output and error logs, you can simply say
    String outFile = "/tmp/sysout.log";
    System.setOut(new PrintStream(new FileOutputStream(outFile)));
    String errFile = "/tmp/syserr.log";
    System.setOut(new PrintStream(new FileOutputStream(errFile)));

Sometimes its required to hide all System.out.println outputs when the existing application is unnecessarily writing lot of outputs filling the system space and it would take some time to modify all the code. To do this, you can subclass PrintStream and override its methods for no-op.

    System.out.println("Hello, program started.");
    String filename = "D:\\sysout.log"; //or put some dummy filepath, need to this to construct PrintStream
    System.setOut(new PrintStream(new FileOutputStream(filename)) {
   
                @Override
                public void print(String paramString) {
                  //do nothing
                }

                @Override
                public void println(String paramString) {
                  //do nothing
                }
                
                //above will just hide the output for print(String) and println(String) methods.
                //override all other print/println methods so nothing gets printed at all.
              }
            );
    System.out.println("This is another string in sysout.");

Monday, September 19, 2011

Oracle Application R12 release setup

Few important environment variables and filepaths:

$CONTEXT_FILE
gives the context file which should be used to any global permanent update to the instance.

$INST_TOP/ora/10.1.3/j2ee/oacore/application-deployments/oacore/orion-application.xml
stores information about OC4J server classpath.

$INST_TOP/ora/10.1.3/j2ee/oacore/application-deployments/oacore/html/orion-web.xml
stores information about servet and jsp settings. New servlet needs to be defined here. If new jsps are added to the instance and they not getting recompiled automatically, following setting needs to be set for main_mode parameter in this file. Usually this setting is set to justrun which does not compile new jsp files.

      <init-param>
         <param-name>main_mode</param-name>
         <param-value>recompile</param-value>
      </init-param>

Classpath for the Java Concurrent programs should be set in adovars.env file.

Look for following element in $CONTEXT_FILE
 <oa_environment type="adovars">
This element will contain parameters for actual adovars file referred by instance. Sometimes there can be multiple adovars environment files on the instance and this should point to currently used adovars file.

Set the value for AF_CLASSPATH element tag to append or prepend classpath for concurrent programs.

$INST_TOP/ora/10.1.3/j2ee/oacore/config/oc4j.properties
Use this file to setup new system properties for OC4J. For Configurator users, you will find cz init properties file reference in this file.

$INST_TOP/logs/ora/10.1.3/
All log files are available here under respective directories like Apache, j2ee, oacore etc.

Apache/OC4J start/stop server scripts are available under $INST_TOP/admin/scripts/

Sunday, September 11, 2011

Print incoming and outgoing cookie through Apache Access log

Sometimes its really very useful to print the incoming and outgoing cookie (or any other http header) from Apache Server to debug Http Session or Loan Balancer related issues.

We can modify the LogFormat in httpd.conf file to print our custom logging. Following format will print incoming and outgoing cookies.

"%h %l %u %t %T \"%r\" %>s %b\n\t\t\t\
   Cookie %{Cookie}i\n\t\t\t\
   Set-Cookie %{Set-Cookie}o"

Saturday, September 10, 2011

Get Log4j File names dynamically for all registered loggers

Use following code to get the filenames registered for logging in log4j.xml file and use them to do whatever you want. Usually the processes in organization will take longer to get the log files, can you do something useful from this? Think and do it on your own and don't document it ever :)

    Enumeration currentLoggers = Logger.getRootLogger().getLoggerRepository().getCurrentLoggers();
    while (currentLoggers.hasMoreElements()) {
      Logger logger = (Logger)currentLoggers.nextElement();
      System.out.println("Logger : " + logger.getName());
      Enumeration loggerApp = logger.getAllAppenders();
      if (loggerApp.hasMoreElements()) {
        Appender ap = (Appender) loggerApp.nextElement();
        if (ap instanceof FileAppender) {
          FileAppender fileAppender = (FileAppender)ap;
          System.out.println("   FileName : " + fileAppender.getFile());
        }else{
          System.out.println("Not a file Appender, appender type=" + ap.getClass().getName());
        }
      }
    }

Thursday, September 1, 2011

Oracle Configurator

Oracle Configurator is
  • an SCM (Supply Chain Management) family product in Oracle Applications
  • integrates with Order Management, Quoting, iStore and other custom applications allowing them to configure its product.
  • helps in building a Guide Selling flow
  • allows the product to be configured according to custom defined rules and User Interfaces (UIs).
  • manages the set of UIs (publications) for different application for different effectivity dates.
  • has CZ as code name in Oracle Applications
  • webbased product
From Oracle's website
Oracle Configurator application integrates with Oracle CRM and Supply Chain Management so you can offer guided selling to your customers. It actively gathers customer requirements and then maps them to a set of product or service options. Oracle Configurator supports Internet sales and telesales as well as other channels.

What to expect from this product:

To easily understand the end result CZ product, visit Dell website and configure any laptop.
While configuring the laptop, you will find that some items in the laptop product (like RAM and OS, Port and respective Accessories) may not be compatible with each other. Like, Windows Vista is not compatible with less than 1GB RAM. You may see some items selected/deselected automatically when you select certain items. You will also see some items appearing and disappearing in webpage UI based on certain selections.

Such compatibility and incompatibility of the items in product are created and managed by product developer. These are called Rules in CZ. CZ Rules can select/deselect certain items based on defined criteria.
The display layout of certain items, and their visibility/invisibility is defined in CZ UIs.
Once, you have the UIs, you can create a copy (although copy not an appropriate term, but gives good understanding about model publications) of UIs and send it to various applications registered in Oracle Applications. Process of creating this backup copy is called Publications.

Well, above example talked only about Laptop product model. You can create Rules and UIs for any product (having however complex its structure may be, usually a BOM-Bill of Materials model).
In addition to product's defined structure items, you can create additional nodes/items (in CZ, they are called non-BOM nodes) in the product model which help to create guided selling flow for the product. Like in above laptop example, first you may select the use of the laptop (like Home-use or Office-use) and certain selections will be made automatically (through CZ rules) for you to create laptop configuration according to selected requirement.