Feed aggregator

Windows XP SP3 crashing JDeveloper 10.1.3.3

Eduardo Rodrigues - Thu, 2009-04-02 13:37
by Eduardo Rodrigues Attention!!! Today, my Windows XP automatically upgraded to SP3 and, after rebooting, my JDev 10.1.3.3 began to crash during its initialization, generating a JVM core dump in...

This is a summary only. Please, visit the blog for full content and more.

A comprehensive XML processing benchmark

Eduardo Rodrigues - Thu, 2009-04-02 13:37
by Eduardo Rodrigues h4 { margin-bottom: 0; font-style: italic; font-size: 110%; text-decoration: none; }Introduction I think I've already mentioned it here but, anyway, I'm currently leading a very...

This is a summary only. Please, visit the blog for full content and more.

Fixed blog's appearance on IE6

Eduardo Rodrigues - Thu, 2009-04-02 13:37
Great news folks! We've just fixed our blog's template so it'll be displayed 100% correctly on Internet Explorer 6 browser. Now, we expect this blog to render identically on both Internet Explorer...

This is a summary only. Please, visit the blog for full content and more.

Is there a cook in JDev's team?

Eduardo Rodrigues - Thu, 2009-04-02 13:37
This week I found something at least very curious when I launched my JDeveloper 10.1.3.3 as I do almost every morning. This was the "Tip of the Day" it showed me: Well, I don't know what this...

This is a summary only. Please, visit the blog for full content and more.

There's a cook in JDev's development team indeed

Java 2 Go! - Thu, 2009-04-02 13:37
Sometime ago I was surprised with a peculiar "tip of the day" which simply mentioned a traditional angel cake recipe. Well, today I got the confirmation. There's certainly a cook amongst JDev's...

This is a summary only. Please, visit the blog for full content and more.
Categories: Development

Windows XP SP3 crashing JDeveloper 10.1.3.3

Java 2 Go! - Thu, 2009-04-02 13:37
by Eduardo Rodrigues Attention!!! Today, my Windows XP automatically upgraded to SP3 and, after rebooting, my JDev 10.1.3.3 began to crash during its initialization, generating a JVM core dump in...

This is a summary only. Please, visit the blog for full content and more.
Categories: Development

A comprehensive XML processing benchmark

Java 2 Go! - Thu, 2009-04-02 13:37
by Eduardo Rodrigues h4 { margin-bottom: 0; font-style: italic; font-size: 110%; text-decoration: none; }Introduction I think I've already mentioned it here but, anyway, I'm currently leading a very...

This is a summary only. Please, visit the blog for full content and more.
Categories: Development

Fixed blog's appearance on IE6

Java 2 Go! - Thu, 2009-04-02 13:37
Great news folks! We've just fixed our blog's template so it'll be displayed 100% correctly on Internet Explorer 6 browser. Now, we expect this blog to render identically on both Internet Explorer...

This is a summary only. Please, visit the blog for full content and more.
Categories: Development

Is there a cook in JDev's team?

Java 2 Go! - Thu, 2009-04-02 13:37
This week I found something at least very curious when I launched my JDeveloper 10.1.3.3 as I do almost every morning. This was the "Tip of the Day" it showed me: Well, I don't know what this...

This is a summary only. Please, visit the blog for full content and more.
Categories: Development

jmp'ing around Win64 with ml64.exe and Assembly Language

Mark A. Williams - Thu, 2009-04-02 13:26

I've been fascinated by (and interested in) assembly language for a number of years. I fondly remember my "Peter Norton Assembly" book and wish I hadn't sent it to a better home several years ago. But, hey, it was a major moving of house and I had to have as few items as possible. The sacrifices we make…

Anyway, I had some spare time this past weekend and decided to try and see if I could get a simple 64-bit assembly language program working under Win64. My goal was to write some text to a console window and exit without destroying my entire system. I managed to succeed in that endeavor and had a bit of fun along the way. My wife thinks I have a bizarre definition of fun. If you continue to read the rest of this post keep in mind I said I was "interested" in assembly. By no means is this intended to be a tutorial or guide in writing efficient and professional assembly! As the comments in the code indicate, there was no attempt at optimization, etc!

A couple of links that I ran across and found helpful (Links accurate as of today. Who knows what the future may bring?):

- Matt Pietrek's X64 Primer column from the May 2006 MSDN Magazine found here.

- Raymond Chen's Blog (The Old New Thing) posting entitled "The History of Calling Conventions, Part 5: AMD64" found here.

In order to make the code just a tiny bit more interesting I decided to call the "cpuid" function to get the Vendor ID from the processor and write that out as well as some static text. Information on the "cpuid" function is available in pdf format on both the Intel and AMD websites. One thing that I found funny is that the 4 byte chunks (of which there are 3) that make up the output of the Vendor ID request from the "cpuid" function are stored in the registers in an "out of order" fashion. Look at the code below that gets the chunks from the registers and you'll see what I mean (I hope).

My First-Ever 64-bit Assembly Language Program With Comments and Everything

NOTE: Edits made per comment(s)

; a (very) simple x64 masm (ml64.exe) demo that calls the cpuid function
; and writes the results to a console window.

; this is just an experiment and is likely not very good assembly code
; for one thing there is no attempt at optimization (like removing duplicate
; sections of code).

; args are passed in registers as follows:
; RCX: 1st integer argument
; RDX: 2nd integer argument
; R8: 3rd integer argument
; R9: 4th integer argument
; the stack is used for args beyond 4 (after space reserved for first 4)
; this reserved space on the stack for first 4 arguments is the
; "register parameter stack area"

; unlike win32 the caller is responsible for cleaning the stack rather than
; the callee

; win api functions that are called below

extrn GetStdHandle : proc
extrn WriteFile    : proc
extrn lstrlen      : proc
extrn ExitProcess  : proc

; the variables used in the main code below such as the text to write

.data
hFile        qword 0
msglen       dword 0
BytesWritten dword 0
supp         byte  13, 10, 'CPUID instruction supported!', 13, 10, 0
nosupp       byte  13, 10, 'CPUID instruction NOT supported!', 13, 10, 0
vndrid       byte  13, 10, "The processor Vendor ID is 'xxxxxxxxxxxx'.", 13, 10, 0

; and we're off...

.code
main proc 
  ; edited Tuesday, 31 March 2009
  ; registers that should be preserved (non-volatile)
 
  push    rbx           ; save (preserve) register
  push    rbp           ; save (preserve) register
  push    rsi           ; save (preserve) register
  push    rdi           ; save (preserve) register
  push    r12           ; save (preserve) register
  push    r13           ; save (preserve) register
  push    r14           ; save (preserve) register
  push    r15           ; save (preserve) register

  sub rsp, 28h          ; adjust stack for local storage if needed 
                        ; and align on a 16 byte boundary

  ; get the handle for the console window to use when writing text
  ; this is used by WriteFile win api function below

  mov ecx, -11          ; put -11 (STD_OUTPUT_HANDLE) into ecx (dword)
  call GetStdHandle     ; call win api to get console handle
  mov hFile, rax        ; move returned handle to hFile

  ; check that the cpuid instruction is supported
  ; this is very likely supported, but here for completeness

  ; taken from the AMD64 Architecture Programmer’s Manual
  ; Volume 3: General-Purpose and System Instructions

  pushfq                ; save EFLAGS
  pop rax               ; store EFLAGS in RAX
  mov rbx, rax          ; save in RBX for test
  xor rax, 200000h      ; toggle bit #21 (i.e. 22nd bit)
  push rax              ; put result on stack
  popfq                 ; save changed RAX to EFLAGS
  pushfq                ; push EFLAGS onto stack
  pop rax               ; store EFLAGS in RAX
  cmp rax, rbx          ; determine if bit #21 changed
  je no_cpuid           ; cpuid not supported (bit did not change)

  ; cpuid is supported if we did not jump...
  ; so print the message that it is supported and then
  ; jump to location where it is actually performed

  lea rcx, supp         ; load address of supp text into rcx
  call lstrlen          ; call win api function to get length of text
  mov msglen, eax       ; move length of string from eax to msglen

  lea r9, BytesWritten  ; LPDWORD lpNumberOfBytesWritten
  mov r8d, msglen       ; DWORD nNumberOfBytesToWrite
  lea rdx, supp         ; LPCVOID lpBuffer
  mov rcx, hFile        ; HANDLE hFile
  call WriteFile        ; call win api to write text to console

  jmp do_cpuid          ; jump over the no_cpuid code path

no_cpuid:
  lea rcx, nosupp       ; load address of nosupp text into rcx
  call lstrlen          ; call win api function to get length of text
  mov msglen, eax       ; move length of string from eax to msglen

  lea r9, BytesWritten  ; LPDWORD lpNumberOfBytesWritten
  mov r8d, msglen       ; DWORD nNumberOfBytesToWrite
  lea rdx, nosupp       ; LPCVOID lpBuffer
  mov rcx, hFile        ; HANDLE hFile
  call WriteFile        ; call win api to write text to console

  jmp exit              ; the no support message was written, so exit

do_cpuid:
  lea rcx, vndrid       ; load address of vndrid text into rcx
  call lstrlen          ; call win api function to get length of text
  mov msglen, eax       ; move length of string from eax to msglen

  xor eax, eax          ; 0 indicates we want the vendor id string
  cpuid                 ; invoke the cpuid instruction to get the string
                        ; the results are now in ebx, edx, and ecx

  ; replace the 'x' placeholders with the vendor id
  lea r9, vndrid

  mov [r9+30], ebx      ; the first 4 bytes of the vendor id
  mov [r9+34], edx      ; the next 4 bytes of the vendor id
  mov [r9+38], ecx      ; the final 4 bytes of the vendor id

  lea r9, BytesWritten  ; LPDWORD lpNumberOfBytesWritten
  mov r8d, msglen       ; DWORD nNumberOfBytesToWrite
  lea rdx, vndrid       ; LPCVOID lpBuffer
  mov rcx, hFile        ; HANDLE hFile
  call WriteFile        ; call win api to write text to console

; edited Tuesday, 31 March 2009
exit:

  add     rsp, 28h      ; clean up the stack

  pop     r15           ; restore preserved register
  pop     r14           ; restore preserved register
  pop     r13           ; restore preserved register
  pop     r12           ; restore preserved register
  pop     rdi           ; restore preserved register
  pop     rsi           ; restore preserved register
  pop     rbp           ; restore preserved register
  pop     rbx           ; restore preserved register 

  xor ecx, ecx          ; xor ecx (set to 0) for return value
  call ExitProcess      ; call win api to exit
main endp

end

The command I used to compile the above is (apologies if wrapping make it difficult to read):

ml64 test64.asm /link /subsystem:console /defaultlib:"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\x64\kernel32.lib" /entry:main

And for the moment of truth…

C:\My Projects\Test\ASM\test>test64

CPUID instruction supported!

The processor Vendor ID is 'GenuineIntel'.

Hurray! Unless you sell AMD chips then you might think 'AuthenticAMD' would look better…

If you see something profoundly wrong in the above, please let me know. It's not like I am going to be churning out assembly code all of a sudden, but I would still be interested in knowing…

Sum to Parent Nodes in Hierarchy Queries: CONNECT_BY_ROOT

Duncan Mein - Sun, 2009-03-29 06:49
In one of our Applicaitons, the table DEPT contains a self referncing join (Pigs Ear) as it models our organsational department hierarchy.

For example:

CREATE TABLE DEPT
(
DEPT_ID NUMBER NOT NULL
,PARENT_ID NUMBER
,DEPT_NAME VARCHAR2 (100) NOT NULL
,EMPLOYEES NUMBER NOT NULL
,CONSTRAINT DEPT_PK PRIMARY KEY (DEPT_ID)
,CONSTRAINT DEPT_FK01 FOREIGN KEY (PARENT_ID)
REFERENCES DEPT (DEPT_ID)
);

INSERT INTO DEPT VALUES (1,NULL,'IT', 100);
INSERT INTO DEPT VALUES (2,1,'DEVELOPMENT', 12);
INSERT INTO DEPT VALUES (3,1,'SUPPORT', 15);
INSERT INTO DEPT VALUES (4,1,'TEST', 25);

INSERT INTO DEPT VALUES (5,2,'PL/SQL', 2);
INSERT INTO DEPT VALUES (6,2,'Java', 1);
INSERT INTO DEPT VALUES (7,2,'SQL', 11);
INSERT INTO DEPT VALUES (8,2,'C++', 3);

INSERT INTO DEPT VALUES (9,4,'Functional', 3);
INSERT INTO DEPT VALUES (10,4,'Non Functional', 5);

COMMIT;
A quick tree walk using CONNECT BY PRIOR shows you the Parent / Child relationships between all departments and the number of employees in each department:
SELECT rpad( ' ', 1*level, ' ' ) || dept_name dept_name
,employees
FROM dept
START WITH parent_id is null
CONNECT BY PRIOR dept_id = parent_id;

DEPT_NAME EMPLOYEES
-------------------- ----------
IT 100
DEVELOPMENT 12
PL/SQL 2
Java 1
SQL 11
C++ 3
SUPPORT 15
TEST 25
Functional 3
Non Functional 5

We had a requirment to work out the total number of employees at each parent level in the Organisational Hierarchy. For example, the report sum up all employees in the parent node and all its children.

Taking the department TEST as an example, the report should sum the figures 25 (employees in the TEST department), 3 and 5 (employees in the Functional / Non Functional child departments) to give a figure of 33.

This can easily be achieved by using CONNECT_BY_ROOT. Straight from the Oracle Documentation:

"CONNECT_BY_ROOT is a unary operator that is valid only in hierarchical queries. When you qualify a column with this operator, Oracle returns the column value using data from the root row. This operator extends the functionality of the CONNECT BY [PRIOR] condition of hierarchical queries.

Restriction on CONNECT_BY_ROOT You cannot specify this operator in the START WITH condition or the CONNECT BY condition.
"

To meet our requirement, CONNECT_BY_ROOT was utilised as follows:

select dept_name, employees, tot_employees
from (select
employees,
dept_name,
level lev,
sum(employees) over(partition by connect_by_root
(dept_id)
) tot_employees
from dept
connect by prior dept_id = parent_id)
where lev=1;

DEPT_NAME EMPLOYEES TOT_EMPLOYEES
-------------------- ---------- -------------
IT 100 177
DEVELOPMENT 12 29
SUPPORT 15 15
TEST 25 33
PL/SQL 2 2
Java 1 1
SQL 11 11
C++ 3 3
Functional 3 3
Non Functional 5 5

Book Review: Processing XML documents with Oracle JDeveloper 11g

Pawel Barut - Sun, 2009-03-29 05:55
Written by Paweł Barut
This time I would like to recommend a book Processing XML documents with Oracle JDeveloper 11g published by PacktPub.com. As I have some experience with XML processing inside Oracle DB (XMLDB) I was lacking the knowledge of XML manipulation in Java, especially using Oracle JDeveloper. This book is rather not for beginners - you should have basic knowledge of what is XML, at least theoretically. From the book you can learn how to manage XML Schemas in JDeveloper, then write XML documents based on those schema and finally validate them in JDeveloper or write Java code to validate it automatically. Chapters that I value much are those describing how to generate PDF documents. There are two methods described - one using Apache FOP API , and Oracle XML Publisher. As I was not generating PDF's this way so far, I found those 2 chapters very interesting. There is also chapter on generatin Excel by transformation of XML using Apache HSSF API .

Book is very practical. If you want to start with subjects described above then this book is for you. Of course it does not mean that you do not have to study documentation. However, it will be easier for you to make first steps. Beside describing Oracle JDeveloper, author also shows how to install and use Oracle Berkley XML DB to store, query and update XML Documents - using command line and XML DB API.

I especially recommend eBook version. All URLs in eBook version are active, so linking to web pages are very simple. Also coping sample code is easy. This book contains many practical and usefull tips on XML processing and tools as well. So if those XML aspects are in your interest, then it's definitelly good to invest in this book.

Keep reading,
Paweł

--
Related Articles on Paweł Barut blog:
    Categories: Development

    ODP.NET Tip: Bind Variables, the BindByName Property, and PL/SQL Function Return Values

    Mark A. Williams - Tue, 2009-03-24 20:25

    A question was posed as a follow-up to a previous post here:

    http://oradim.blogspot.com/2007/08/odpnet-tip-bind-variables-and.html

    The poster wanted to know if you have set BindByName to "true" for an OracleCommand object and the command text for that object calls a PL/SQL function (which of course has a return value but no name), what name should you give to the parameter object that will receive the return value? It's a good question since BindByName set to "true" implies that you've given names to your bind variables!

    The short answer is: It doesn't matter as it will be ignored anyway.

    As in The Highlander movies, with return values, there can be only one. You can set ParameterDirection to "ReturnValue" for multiple parameters, but it is an error to do so. Try it and see what errors are raised.

    Here's a quick little demo showing that it does not matter what name you give to the parameter that you declare as the return value.

    First create a simple PL/SQL function (so that there is a return value!) like this:

    create or replace function subtract_numbers(p1 in number, p2 in number) return number as
    begin
      return p1 - p2;
    end;
    /

    I've elected to do a simple bit of subtraction and this is for a reason. Since in subtraction the order of the parameters matters, it is easy to show that the parameters are being handled in the correct order. As you'll see in the sample code below, I use the values "48" and "2" so it would be obvious if the ordering were reversed.

    Now, here's some simple (and normal caveats about no error handling, etc. apply) bit of C# to illustrate the point:

    using System;
    using System.Data;
    using Oracle.DataAccess.Client;
    using Oracle.DataAccess.Types;

    class Program
    {
      static void Main(string[] args)
      {
        // adjust connect string to suit your environment
        string constr = "user id=hr;" +
                        "password=hr;" +
                        "data source=orademo;" +
                        "pooling=false;" +
                        "enlist=false";

        // create and open connection
        OracleConnection con = new OracleConnection(constr);
        con.Open();

        // create command object
        OracleCommand cmd = con.CreateCommand();
        cmd.CommandText = "subtract_numbers";
        cmd.CommandType = CommandType.StoredProcedure;

        // set bindbyname to true so parameters can be added
        // in any order and to illustrate what happens with a
        // return value
        cmd.BindByName = true;

        // the first input parameter to the pl/sql function
        OracleParameter p1 = new OracleParameter();
        p1.Direction = ParameterDirection.Input;
        p1.OracleDbType = OracleDbType.Int64;
        p1.ParameterName = "p1";
        p1.Value = 48;

        // the second input parameter to the pl/sql function
        OracleParameter p2 = new OracleParameter();
        p2.Direction = ParameterDirection.Input;
        p2.OracleDbType = OracleDbType.Int64;
        p2.ParameterName = "p2";
        p2.Value = 2;

        // the return parameter from the pl/sql function
        OracleParameter p3 = new OracleParameter();
        p3.Direction = ParameterDirection.ReturnValue;
        p3.OracleDbType = OracleDbType.Int64;
        p3.ParameterName = "ignored";

        // add the parameters in a "wrong" order since
        // bindbyname is true -- this is key
        cmd.Parameters.Add(p1);  // input #1
        cmd.Parameters.Add(p3);  // return value
        cmd.Parameters.Add(p2);  // input #2

        // execute the stored pl/sql code
        cmd.ExecuteNonQuery();

        // write the result to the console window
        Console.WriteLine("The difference of {0} and {1} is {2}",
          p1.Value, p2.Value, p3.Value);

        // prevent console window from closing when run from VS
        Console.WriteLine();
        Console.Write("ENTER to continue...");
        Console.ReadLine();
        // clean up
        p3.Dispose();
        p2.Dispose();
        p1.Dispose();
        cmd.Dispose();
        con.Dispose();
      }
    }

    Notice how the parameters are added to the parameter collection "out of order". This is OK since BindByName is set to "true". You can comment out the line that sets BindByName and see an exception raised if you want. Anyway, when I execute this code, I get the expected results as follows:

    The difference of 48 and 2 is 46

    ENTER to continue...

    So, even though the return value parameter was added to the collection in the second position everything works as desired. Yes, but I gave it a name of "ignored" so how do we know that name is not really being used? Well there are two easy ways to find out. One, just don't give the parameter a name at all and everything should continue to execute just fine. It's easy to ignore a name that's not there! Or, two, if you are an inquisitive type, enable SQL tracing (search the web for 10046 trace -- you'll find a million hits) and see what ODP.NET actually sent to the database. Here's a snippet of a trace file from the above code (with the parameter name of "ignored" in place):

    PARSING IN CURSOR #2 len=54 dep=0 uid=82 oct=47 lid=82 tim=10601980885 hv=1771638930 ad='7ff39775518' sqlid='gx0kvypntk44k'
    Begin :ret := subtract_numbers(p1=>:v0, p2=>:v2); End;
    END OF STMT
    PARSE #2:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=10601980885
    BINDS #2:
    Bind#0
      oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=00 csi=00 siz=72 off=0
      kxsbbbfp=1bb2dd60  bln=22  avl=00  flg=05
    Bind#1
      oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=00 csi=00 siz=0 off=24
      kxsbbbfp=1bb2dd78  bln=22  avl=02  flg=01
      value=48
    Bind#2
      oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=00 csi=00 siz=0 off=48
      kxsbbbfp=1bb2dd90  bln=22  avl=02  flg=01
      value=2

    See how ODP.NET generated a little anonymous block and substituted "ret" for the return value parameter? You should see the same thing even if there is no name given to the return parameter. You can also clearly see how the input parameter names are associated with the input values.

    Check All / Uncheck All Checkbox

    Duncan Mein - Tue, 2009-03-24 09:14
    There is a really cool JavaScript function in Apex called: $f_CheckFirstColumn that allows you to Check / Uncheck all checkboxes that exist in the 1st column position of a Tabular Form / Report.

    To implement this, all you need do is add the following HTML to the Column Heading of the 1st Column in your Tabular Form (i.e. the Checkbox Column):

    <input type="Checkbox" onclick="$f_CheckFirstColumn(this)">

    Check out an example here

    Data Mining Survey - Last Call

    Marcos Campos - Tue, 2009-03-24 08:41
    Rexer Analytics has just issued a last call for its annual data mining survey. This is a pretty nice survey that provides a great deal of valuable information about how data mining is used and who is doing it. To participate, please click on the link below and enter the access code in the space provided. The survey should take approximately 20 minutes to complete.  At the end of the survey you Marcoshttp://www.blogger.com/profile/14756167848125664628noreply@blogger.com2
    Categories: BI & Warehousing

    Ada Lovelace Day

    Stephen Booth - Tue, 2009-03-24 07:23
    Apparently today is Ada Lovelace Day. Ada Lovelace (aka Augusta Ada King, Countess of Lovelace) is widely recognised as the first computer programmer. The daughter of Lord Byron, she was encouraged away from her father's dissolute lifestyle by her mother, who encouraged her interest in mathematics. Ada excelled at mathematics and became a friend for Charles Babbage.When Babbage created his Stephen Boothhttps://plus.google.com/107526053475064059763noreply@blogger.com0

    ActiveRecord Oracle enhanced adapter also on JRuby and Ruby 1.9

    Raimonds Simanovskis - Sun, 2009-03-22 17:00

    So far if you wanted to use Ruby on Rails on Oracle database you needed to use different adapters depending on the Ruby platform that you wanted to use. If you used original MRI (Matz Ruby interpreter) 1.8.6 then hopefully you were using Oracle enhanced adapter. But if you wanted to use JRuby then you needed to use JDBC adapter that is maintained by JRuby team (and which sometimes might work differently than Oracle enhanced adapter). And if you wanted to use new Ruby 1.9.1 then you were out of luck as no adapter supported it.

    Therefore I wanted to announce great news that ActiveRecord Oracle enhanced adapter 1.2.0 is released and it supports all three major Ruby platforms!

    • Use Oracle enhanced adapter on MRI 1.8.6 with ruby-oci8 1.0.x library or gem
    • Use Oracle enhanced adapter on JRuby (so far tested with 1.1.6) with JDBC Oracle driver
    • Use Oracle enhanced adapter on Ruby/YARV 1.9.1 with ruby-oci8 2.0 library or gem

    This provides you with much more flexibility to develop on one Ruby platform but deploy on another and on all three platforms you can use the same additional functionality that Oracle enhanced adapter provides on top of standard ActiveRecord functionality.

    And during testing of Oracle enhanced adapter on all platforms additional milestone was achieved – Oracle enhanced adapter passes 100% ActiveRecord unit tests! But to be honest I need to tell that I needed to patch quite many unit tests for Oracle specifics as not all SQL that runs on MySQL is also valid on Oracle. I published my patched branch of ActiveRecord unit tests at my GitHub fork of Rails – you can clone the repository and verify by yourself.

    So please try out new version of Oracle enhanced adapter on any Ruby platform:

    gem install activerecord-oracle_enahnced-adapter

    If you have any questions please use discussion group or post comments here. In nearest future I will also add more instructions how to install Oracle enhanced adapter on JRuby and Ruby 1.9.1 at GitHub wiki page.

    Categories: Development

    Rollback segments explained

    Oracle WTF - Fri, 2009-03-20 02:57

    I recently read this in a book about data warehousing:

    Source System Rollback SegmentsWhen extracting from a relational source, extracts that take a long time can be problematic. If an extract asks for all records updated in the last 24 hours, the system must locate the appropriate set of records. This means that no user can change the updated_date field while your query is being processed. As transactions flow in during your query, they are queued up in a separate place called a rollback segment, to be applied once your request is finished. If your query takes too long, this queue gets too large and runs out of space. The system then kills your job and processes the transactions that have been queued up. In general, the folks responsible for the transaction system don't like this kind of behavior.

    Now to be fair, the book was published in 1998 and is not specifically about Oracle. Does anyone know whether there has ever been a commercial DBMS that worked anything like this, or did they just make it up?

    Core ADF 11: Designing the Page and Taskflow Structure

    JHeadstart - Fri, 2009-03-20 00:53

    JDeveloper's tagline is "productivity with choice". In previous releases this choice merely applied to the various technologies that could be used in each of the ADF layers. With release 11 this has changed. When choosing the "Fusion" technology stack within ADF (ADF Faces, ADF Task Flows and ADF Business Components), there are many new and powerful concepts and techniques available that allow you to build the required functionality in different ways. Concepts like (un)bounded taskflows, page fragments, (dynamic) regions, page templates, declarative components, declarative transaction support, XML Menu Model, ADF Faces Layout Components and ADF Libraries open up a wide range of new possibilities to build the view and controller layers.

    These new possibilities imply that new design decisions must be made on how to build the required functionality. This is not a trivial task. Many of the concepts relate to each other, and choosing how to use one concept can have impact on the usage of other concepts. I admit that's pretty vague, but in this new "Core ADF 11" series, we (the JHeadstart team) will try to make this more concrete. In this series we will share with you the experiences, issues, challenges, design considerations, design decisions and best practices that we faced/encountered/developed when building JHeadstart release 11.

    Note that we will assume that you have a basic understanding of the new ADF 11 concepts. If this is not the case, we recommend you take the ADF 11 course from Oracle University, or if you prefer self-study, take a look at the ADF Learning Center.

    In this first post, we will start at the beginning: you want to build your first "serious" ADF 11 page, and you immediately need to choose: do I create a page or a page fragment, do I base the page (fragment) on a template, and do I put the page in an unbounded or bounded task flow.

    Page Templates
    This one is easy: we recommend to always use a page template. Design the template whatever way you want but make sure you include all the UI elements that need to be displayed on each and every page. Typical content of a page template include a branding image/application logo, global actions like Home, Help, Log Out, Preferences, the menu of the application (either a tree menu, or various levels of navigation panes like tabs, buttons or lists) and a footer area with for example a copyright message. Use page template attributes to pass in properties that might differ between pages like the page title, and to conditionally show/hide parts of the page template for specific pages. In a later post, we will go into more details on designing page templates.
    Note that you can also dynamically change the page template associated with a page at runtime. Instead of hardcoding the page template path, you can use an EL expression that binds to a look and feel bean that contains the current page template path.

    Bounded or Unbounded Taskflows
    Each ADF 11 web application has one unbounded taskflow, and can have one or more bounded task flows. So, the choice is not so much about using bounded or unbounded task flows, but about putting a JSF page inside the unbounded taskflow, or inside a bounded task flow.
    When building transactional applications, bounded task flows have major advantages over unbounded task flows. For a start, bounded task flows support additional features that can be very useful when building transactional applications:

    • Save for Later
    • Declarative Transaction Support
    • Exception Handling
    • Own Memory Scope
    • Back button handling

    In addition, bounded task flows allow you to benefit from concepts well-known in the world of object oriented programming and component-based development. Using bounded task flows:

    • you can create truly reusable user interface components through page fragments and regions;
    • with a well-defined service contract; through taskflow parameters you can configure the behavior of the taskflow;
    • that are loosely coupled; to use a task flow, you only need to know about the available task flows parameters. The internal flow, structure of user interface components and data structures can be changed without any impact on the pages or other taskflows that are using/calling the taskflow.

    In short, well-designed bounded task flows have many advantages over the unbounded task flow. We recommend to only use the unbounded task flow for introductionary pages like the home page or a UI shell page when using regions (see below). All application uses cases should be implemented using a bounded task flow. In a later post in this series, we will discuss in more detail how to design your task flows for maximum reusability.

    Stand-alone Pages or Page Fragments with (Dynamic) Regions
    For your page design, you basically have three choices

    • Create stand-alone .jspx pages
    • Create .jsff page fragments within a region, and create a shell page for each region that contains the af:region tag.
    • Create .jsff page fragments within a region, and create one common UI shell .jspx page, that uses a dynamic region to display the requested region. This is the "One Page Application" model, where the UI shell page is the only .jspx page in the application, and a menu displayed in the shell page is used to set the current region displayed on the page.

    Some considerations and implications to take into account for each choice:
    Stand-alone pages:

    • Stand-alone pages are easiest to build and understand, it is like building your app the "10.1.3 way".
    • Stand-alone pages offer little reuse, they cannot be used inside regions
    • When you are building a menu-driven application, and each menu entry starts a bounded taskflow with stand-alone pages, there is no easy way to abandon the current task flow. When the user wants to leave the current task flow and clicks on another menu entry, nothing will happen! This is because the control flow case to start the taskflow associated with the other menu item is defined in the unbounded task flow, which is not reachable once a bounded taskflow is started. The easy solution is to not use bounded task flows at all. You will lose all the advantages of bounded task flows, but when simplicity is more important to you then reusability, this is a valid choice. We discuss a more sophisticated solution to the "abandon taskflow with stand-alone pages issue" in this post of the ADF 11 Core series.
    • When you are using the XMLMenuModel to create your menu, you can associate one focusViewId with each menu item. If you navigate to the page with this view id, the associated menu item will be highlighted automatically. However, if you then navigate to a detail page from the focusViewId page, you loose the menu item highlighting. In this post, we discuss how you can extend the XMLMenuModel to associate multiple pages with one menu item

    Static regions with shell page:

    • With this design, you leverage the reuse options of bounded task flows with page fragments
    • You do not run into the XMLMenuModel multi-page problem, since each menu item is associated with the shell page which remains the same while navigating between the page fragments within the ADF region embedded in the shell page
    • You do not run into the "abandon task flow" issue that occurs with stand-alone pages, since the shell pages are all located in the unbounded task flow.
    • If you navigate away to another shell page, you need to be aware that ADF will auto-execute some logic to clean up the abandoned task flow of the region in the previous shell page. The actual clean-up logic executed depends on the transaction settings of the task flow. For example, if the task flow started a new transaction, a rollback will be performed. Note that when using shared data controls, the rollback might have a performance impact since already executed queries in other task flows will need to be re-executed as well. In a later post, we will discuss taskflow transaction management in more detail.

    One-page application:
    With the previous design option, a shell page is created for each ADF region. Typically, all these shell pages will be very thin and very similar: they are based on the same page template that renders the menu and other common page components, the only difference is the name of the ADF region that is embedded in the shell page. In a one page application, we create one UI Shell page and use a dynamic region to display the correct region. Here are the implications:

    • Performance increases because partial page rendering can be used to replace the content of the dynamic region, the UI shell page does not need to be reloaded. In our experience, the performance difference is quite significant. However, according to the documentation there is a feature called Partial Page Navigation which would allow for a similar performance when using separate shell pages or stand-alone pages. I did not get this feature to work though.
    • The one-page application raises a problem with XMLMenuModel, opposite to the stand-alone pages design: there is only one page used by all menu items. This can be solved by creating a subclass of XMLMenuModel that highlights the correct menu item based on the currently selected region as set in the dynamic region bean. We will discuss this technique in more detail in a future post.
    • When using a dynamic region, the parameters for all region task flows can be defined against the dynamic task flow binding in the page definition of the UI shell page. This quickly becomes ugly and unmanageable: one long list of parameters for all task flows in the application. A better approach is to use the parameter map property of the dynamic task flow binding, and reference the parameter map of the current region through the dynamic region bean. This technique is discussed in more detail in this post.

    A variation of this implementation is the use of dynamic tabs rather than a dynamic region. This enables multi-tasking for the end user, see this post for more details on the implementation of dynamic tabs.  

    Summary
    While JDeveloper makes it easy to later on convert stand-alone pages to fragments, and unbounded task flows to bounded task flows, it is better to make these design decisions upfront. The choices you make have impact on the usage of XMLMenuModel, menu-driven navigation in general, reusability, transaction management and performance.
    We recommend to use bounded task flows with page fragments to maximize reusability. While traditional transactional applications are mostly menu-driven, composite, task-oriented user interfaces are likely to become mainstream in the future. When you start building your ADF 11 app today using (dynamic) regions accessible from a menu, you can reuse the same task flows when building more task-oriented user interfaces using the WebCenter and Human Workflow capabilities planned for JDeveloper 11 release 2.

    Categories: Development

    Pages

    Subscribe to Oracle FAQ aggregator