Thursday, 16 April 2009

Oracle 11g: Switching to native compilation

One of the most celebrated features of Oracle 11g is supposed to be the PL/SQL native compilation feature. This allows PL/SQL code to be compiled directly into machine code that is also stored inside the database, thus eliminating the need for an external C complier of DLL loader.

Sam R. Alapati and Charles Kim in their Oracle Database 11g New Features for DBA's and Developers book published by APRESS, write that tests performed by Oracle showed an increase in performance of up to 20 times when using native SQL.

There is only one startup parameter that affects the compilation mode of new PL/SQL programs. This parameter is named plsql_code_type and its value can be either 'NATIVE' or 'INTERPRETED'. So doing an :

SQL> alter system set plsql_code_type = 'NATIVE' scope=both;

System altered.

SQL> 

... will effect all new PL/SQL programs that will be created or compiled from this point on. Switching the entire database to use native PL/SQL is a bit more complicated and is performed by following these steps :

  1. Shutdown the database.
  2. Start it up again in upgrade more. (startup upgrade)
  3. Run the $ORACLE_HOME/rdbms/admin/dbmsupgnv.sql script. This will set the execution mode of all database PL/SQL code blocks to native.
  4. Shutdown the database and start it up again in normal mode.
  5. Run the $ORACLE_HOME/rdbms/admin/utlrp.sql script to recompile all invalid PL/SQL code units.

Be advised that the last step may take a considerable amount of time, depending on the number of PL/SQL objects in your database. Oracle provides the following query to test the number of objects left to be compiled.

SQL>  SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6);

  COUNT(*)
----------
      2055

SQL> r   
  1*  SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6)

  COUNT(*)
----------
      2005

SQL> r
  1*  SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6)

  COUNT(*)
----------
      1109

SQL>

One last thing. The process can be reversed, by following the steps above but instead of running dbmsupgnv.sql, run the dbmsupgin.sql also located in $ORACLE_HOME/rdbms/bin.

Tuesday, 7 April 2009

Linux: Getting passed rsync's most notorious error messages and determining whether a shell is interactive or not.

While trying to back up my personal data using rsync -aruvzh --delete /home/thanassis/jdevhome/ thanassis@192.168.1.68:/home/thanassis/jdevhome I run into the following error message.

protocol version mismatch - is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(69)

A little googling and a final look at the rsync manual revealed that :

DIAGNOSTICS
     rsync occasionally produces error messages that may seem a little cryp-
     tic.  The  one that seems to cause the most confusion is “protocol ver-
     sion mismatch — is your shell clean?”.

     This message is usually caused by your startup scripts or remote  shell
     facility  producing  unwanted garbage on the stream that rsync is using
     for its transport. The way to diagnose this  problem  is  to  run  your
     remote shell like this:

            ssh remotehost /bin/true > out.dat

     then  look  at out.dat. If everything is working correctly then out.dat
     should be a zero length file. If you are getting the above  error  from
     rsync  then  you  will probably find that out.dat contains some text or
     data. Look at the contents and try to work out what  is  producing  it.
     The  most  common cause is incorrectly configured shell startup scripts
     (such as .cshrc or .profile) that contain output  statements  for  non-
     interactive logins.

Needless to say that fortune was the one to blame. My .bashrc file had the following last statements since the days of SuSE 8.2 and although I am now using a completely different distro, I still refuse to get them out of my startup files.

# Something to remember the old SuSE days
if [ -x /usr/bin/fortune ] ; then
    echo
    /usr/bin/fortune
    echo
fi

So, the solution would be to display a fortune cookie only when the current shell is interactive and then it was time for the Bash Reference Manual to come to our rescue. Their answers are straightforward :

To determine within a startup script whether Bash is running interactively or not, examine the variable $PS1; it is unset in non-interactive shells, and set in interactive shells. Thus:
     if [ -z "$PS1" ]; then
        echo This shell is not interactive
     else
        echo This shell is interactive
     fi
Alternatively, startup scripts may test the value of the `-' special parameter. It contains i when the shell is interactive. For example:
     case "$-" in
     *i*)  echo This shell is interactive ;;
     *)    echo This shell is not interactive ;;
     esac

In my case I wanted to run fortune on interactive shells only. So again I modified my bashrc file to look like :

# Display a fortune cookie on interactive logins only
if [ -n "$PS1" ]; then
        # Some people don't like fortune. If you uncomment the following lines,
        # you will have a fortune each time you log in ;-)
        if [ -x /usr/bin/fortune ] ; then
                echo
                /usr/bin/fortune
                echo
        fi
fi

... and that did it.

Friday, 27 March 2009

JDevelopr 10g to 11g. It's a long way to migration

Today i tried migrating a simple project from JDeveloper 10g (10.1.3.4) to 11g (11.1.1.0.1) )and the results are mostly disappointing.

A picture is a thousand words.

Migration Results
Browse Page
Search Page
This is how the application looks today. ... and here is how it ended up after migration......

Just for the shake of complicity, I have to report the following :

  • Migration finished without any exceptions being thrown at the console. The only warning message that appears when opening the project is :
    Mar 30, 2009 9:43:18 AM oracle.jdevimpl.webapp.taglib.JDevTaglibUtils _parseFail
    WARNING: Invalid TLD Location, TldUtils parse failed for URL : jar:file:/home/oracle/jdeveloper/mywork/AS400-Materials/ViewController/opt/oracle/Middleware/jdeveloper/jlib/adf-faces-databinding-rt.jar!/META-INF/databinding.tld
        
  • Although attribute labels are not shown in the search page, the Attribute properties page displays them correctly.
  • The initial JSF navigation diagram, does not display any graphic, despite the fact that I see no error ether on the message window or the console.

I feel like I want to complain to somebody, but I am not sure to whom.

Monday, 23 March 2009

Linux: Mind your labels

I had seen labels used in /etc/fstab and /boot/grub/grub.conf but never quite got the hung of them, until I read page 170 of Tammy Fox's Red Hat Enterprise Linux 5 Administration Unleashed.

So what I got out of this, was that labels may be listed in place of partitions and while they are not required, they may become useful when a partition number changes, when moving the partition or repartitioning the drive.

The command to use for changing or displaying a partition's label is e2label. The command must be run as root and the syntax is as simple as :

e2label device [newlabel

This sets label to device and if no label is provided, then the device's label is displayed.

So far so good. Now the sad story begins when attempting to change the label of an existing partition of an already used drive, especially the one containing /boot.

When that happens remember to update both /etc/fstab and /boot/grub/grub.conf. Otherwise you risk not being able to boot your system next time. The default label used by the Anaconda installer is "\". So let's suppose that for some reason you decide to change this to CentOS-Root, by issuing something like :

[root@lxbakalidis ~]# e2label /dev/sda1 CentOS-Root

Next thing to do is check your /etc/fstab file and make sure that an entry like :

LABEL=CentOS-Root       /                       ext3    defaults        1 1

is really there and last but not least make sure that grab.conf line that starts your current kernel also references the new label like this:

title CentOS (2.6.18-92.1.22.el5)
        root (hd1,0)
        kernel /boot/vmlinuz-2.6.18-92.1.22.el5 ro root=LABEL=CentOS-Root rhgb quiet 
        initrd /boot/initrd-2.6.18-92.1.22.el5.img

Failure to do this right will probably halt your kernel with messages like :

mount: could not find filesystem '/dev/root'
setuproot: moving /dev failed: No such file or directory
setuproot: error mounting /proc: No such file or directory
setuproot: error mounting /sys: No such file or directory
switchroot: mount failed: No such file or directory
Kernel panic - not syncing: Attempted to kill init!

... and you will probably need a live CD to fix it. For more information refer to the following thread at LinuxQustions.org.

PS: Now I am sure that the last fortune cookie I saw before the crush read something like Good judgement comes from experience, experience comes from bad judgement. but I was too preoccupied with the coming Friday night joys to take it seriously.

Friday, 13 February 2009

Linux : Creating virtual disks from .iso files

Just picked this up from the fedora guide and and thought I might put it here for reference.

Suppose you have a .ISO file whose contents you wish to examine or even need to copy some data out of. The fedora-guide suggests the following approach.

mkdir ~/your_disc/
su -c 'mount file.iso ~/your_disc -t iso9660 -o loop'

then to unmount it

su -c 'umount ~/your_disc/'

Thursday, 5 February 2009

RealPlayer for 64 bit Linux

This is quick note to myself as I keep forgetting it.

The location to download latest nightly builds for RealPlayer that includes a x86_64 version for Linux is here.

For x86_64 Linux choose the version tagged linux-2.6-glibc23-amd64.

Thursday, 8 January 2009

Linux: Getting past the "BIOS doesn't leave a aperture memory hole" error or "How to enable the IOMMU option in the BIOS setup" . Part 2

After yesterdays post regarding the BIOS doesn't leave a aperture memory hole issue, I got a very logical question that I forgot to ask myself as I was too happy to see the error message go away.

Quirinius said:

But did that boot option actually give you more memory? Did you check with "free -m"?

So I did a little bit of testing. Here is the output of the free command before the using boot-options on the CentOS machine.


  total       used       free     shared    buffers     cached
Mem:       4048440     804072    3244368          0      34324     428640
-/+ buffers/cache:     341108    3707332
Swap:      4200988          0    4200988
      
  total       used       free     shared    buffers     cached
Mem:          3953        785       3168          0         33        418
-/+ buffers/cache:        333       3620
Swap:         4102          0       4102
    

and here is after :


  total       used       free     shared    buffers     cached
Mem:       4048024     553232    3494792          0      30792     336400
-/+ buffers/cache:     186040    3861984
Swap:      4200988          0    4200988
      
  total       used       free     shared    buffers     cached
Mem:          3953        536       3416          0         30        328
-/+ buffers/cache:        177       3775
Swap:         4102          0       4102
    

I have also checked what is happening on my notebook which also has 4GB of RAM memory but unlike the rest of my machines does not have an AMD processor or an Asus Motherboard with Phoenix BIOS and here is what free had to say.


  total       used       free     shared    buffers     cached
Mem:       4059392     652816    3406576          0      13048     206600
-/+ buffers/cache:     433168    3626224
Swap:      2096472          0    2096472
      
  total       used       free     shared    buffers     cached
Mem:          3964        637       3326          0         12        201
-/+ buffers/cache:        423       3541
Swap:         2047          0       2047
    

Doing a little bit of math shows that ...

      [thanassis@lxbakalidis ~]$ expr 4048024 - 4048440
      -416
    

After the boot option is set our memory decreases by 416 bytes and the memory reported by Fedora on a system that does not display the IOMMU error message at all is

      [thanassis@lxbakalidis ~]$ expr 4059392 - 4048440
      10952
    

... bytes bigger. Now I understand that I am comparing results from two different kernel versions, so I performed the same test at home on my AMD/Asus based Fedora box and here are my results..


[thanassis@plouton ~]$ cat fedora-home-before.txt 
             total       used       free     shared    buffers     cached
Mem:       4062232     490440    3571792          0      13816     177132
-/+ buffers/cache:     299492    3762740
Swap:            0          0          0
             total       used       free     shared    buffers     cached
Mem:          3967        479       3488          0         13        172
-/+ buffers/cache:        292       3674
Swap:            0          0          0
[thanassis@plouton ~]$ cat fedora-home-after.txt 
             total       used       free     shared    buffers     cached
Mem:       4061820    1083232    2978588          0      34960     393808
-/+ buffers/cache:     654464    3407356
Swap:            0          0          0
             total       used       free     shared    buffers     cached
Mem:          3966       1055       2910          0         34        384
-/+ buffers/cache:        636       3329
Swap:            0          0          0
[thanassis@plouton ~]$ expr 4061820 - 4062232
-412
[thanassis@plouton ~]$ 
    

Addendum

This is only a closing statement to admit that I managed nothing. I tried changing my graphics adapter with a new NVIDIA using the new kernel updates and my CentOS machine just froze again.

So I switched everything back, got my 416 bytes back and try to keep an eye on the net and the forums in case I somehow find something to help me this.... :-(

Tuesday, 6 January 2009

Linux: Getting past the "BIOS doesn't leave a aperture memory hole" error or "How to enable the IOMMU option in the BIOS setup" .

This had been a major "To Do" item for me during the last year and I have tried many times to fix it, but today it seems I got lucky.

I had been seeing this on my CentOS workstation dmesg output, since the first day I installed it, approximately one year ago.


Checking aperture...
CPU 0: aperture @ 14000000 size 32 MB
Aperture too small (32 MB)
No AGP bridge found
Your BIOS doesn't leave a aperture memory hole
Please enable the IOMMU option in the BIOS setup
This costs you 64 MB of RAM

At first I thought it was nothing serious, and I tried to fix my graphics card that would not work with the NVidia provided drivers freezing the entire graphics system each time I would install them and tried to start X. I failed that too and replaced the graphics card with one from ATI. The new card appeared to work more satisfactory, but it would also hung if I tried to load the custom drivers provided by the vendor.

When I installed Feodra 9 at home, I saw the exact same error message but my GeForce 9600 NVidia appeared to work correctly so I dropped it. Then came Fedora 10 and there we were again. At the same time I began to get tired by the sluggish performance of my CentOS graphics and decided to try once again.

But his time I was lucky : jbkt23 provided the solution at the Fedora Forums. I am only copying it here just to help others who google for it come up with one much match.

Put it simply, the solution is to add the iommu=noaperture kernel boot parameter on your grub.conf file.

In more words, you need to edit the grub configuration file located in /boot/grub/grub.conf and locate the line that boots the current kernel. On my Fedora system the line looks like this :


title Fedora (2.6.27.9-159.fc10.x86_64)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.27.9-159.fc10.x86_64 ro root=UUID=8a9d59ee-c401-41bf-a4e6-8fdd97
067215 rhgb quiet iommu=noaperture
        initrd /boot/initrd-2.6.27.9-159.fc10.x86_64.img

All I needed was to add the bolded text at the end of the kernel line. Then a reboot and as MSK61 from the Fedora forum put it: Thanks, jbkt23. Worked like a charm.

The same solution worked for the CentOS 5.2 machine at work. There is more to it however. After getting rid of the IOMMU error, I tried to enable the 3D driver for my ATI Radeon X1300. At some point it worked. After the first reboot however, things went back to their normal not working state so I had to switch back to the standard driver.

Tomorrow I will try an NVidia card that was also not working and see how it goes.

Wednesday, 19 November 2008

GoogleEarth 4.3: How to change the GUI fontsize in Linux

Just installed GoogleEarth version 4.3 on my CentOS 5.2 machine today.

The installation finished without any errors but the font the GUI started with was a complete disaster. It was so small I could not read it. A little bit of googling revealed the following:

  1. GoogleEarth 4.3 stores it's configuration in the ~/.config/Google directory.
  2. Inside it, the file GoogleEarthPlus.conf contains a section called [Render].
  3. The render section contains attributes for GuiFontFamily and GuiFontSize. Place the right values over there, restart googleearth and that does it.

Thanks to Santana for posting it.

Tuesday, 11 November 2008

JavaScript: Dynamically changing CSS properties of any DOM object

I was trying to create a web album the other day and played around with the gThumb image program. The program offers various templates that allow you to create web galleries with various different styles and it turned out that for me, the BestFit template was the best looking of them all.

The interesting part of the story is that when you create a web gallery based on the BestFit template, you also get a number of JavaScript files containing various programming goodies like the get and set property functions that I am displaying on this post. The copyright of these functions is Copyright (C) 2005-2006 Free Software Foundation, Inc., thus my thanks here go to Rennie deGraaf who provided both the template and the opportunity to get access to these functions.

So changing the width, height, or display mode of any DOM object found in your web page has never been so simple.

// set a property to a given value on an object
function setProperty ( obj, prop, val )
{
    if (obj.style.setProperty) // W3C
        obj.style.setProperty(prop, val, null);
    else // MSIE
        eval("obj.style." + prop + " = \"" + val + "\"");
}
 
// gets a style property for an object
function getProperty ( obj, prop )
{
    if (document.defaultView && 
        document.defaultView.getComputedStyle) {
        var val = document.defaultView.getComputedStyle( obj, 
                    null).getPropertyValue(prop)
        if (val)
            return val;
        else
            return eval("document.defaultView.getComputedStyle(obj,null)." + prop);
    }
    else if (window.getComputedStyle) // Konqueror
        return window.getComputedStyle(obj,null).getPropertyValue(prop);
    else if (obj.currentStyle)        // MSIE
        return eval('obj.currentStyle.' + prop);
}

Thursday, 23 October 2008

Oracle IAS 10g 10.1.3.x Mapping j2ee security roles to OID groups

Today I feel like I have touched down the deepest bottom of applied j2ee. I have spend two hours trying to figure out why mapping of j2ee application roles -- defined in `/META-INF/jazn-data.xml -- to Internet directory groups did not work and all it required was just to restart the OC4J instance. And although I knew the peeps in a Jeep joke, it took me two hours to finally get out and back in again, i.e. do the restart and get over with it.

To be honest, I have always wanted to do that simply by matching j2ee roles and OID groups and then use something as simple as my UserInfo bean to determine allowed user actions. The truth of the matter is that until today I always gave it up after running into the 403 Forbidden reply from Apache popping out after accessing the application..

Anyway, enough with grumbling, my advice to anyone interested in performing the same is: Just when you think you 've finished changing the applications security provider, setting up mappings and deploying the application do a final restart to the instance.

Wednesday, 15 October 2008

Oracle ADF: Verifying Master-Detail relationships and throwing exception on "beforeCommit()" events

I have found no other way to validate master detail hierarchies, than using theEntityImpl.beforeCommit(TransactionEvent transactionEvent). Writing a validateEntity() function can only prove useful when examining the fields of the current record. There are cases however where you need to verify that the entire tree is correct. Consider for instance a cases where you need to verify that all items included in an order are eligible for seeding to the user's dispatch address. For cases like this you need to examine your data just before committing and the beforeCommit() does just that.

During before commit you can practically traverse your entire M/D tree using association accessors and verify that everything meets you business rules.

If anything fails to validate then raising a JboException will prevent the actual commit and the exception error message will appear on your tag in your jspx page. There is however only one small catch:

Unless you modify your application module configuration and set the jbo.txn.handleafterpostexc to true, all exceptions thrown inside the afterCommit() method result in a roll-back which completely destroys the data hierarchy just build. As Steve Muench puts it,

When this flag is true, the framework will take an in-memory snapshot of the pending state of the application module, and then use this snapshot to reinstate that same pending state in case any of the beforeCommit() methods fail with an exception. If everything goes successfully with no errors, the in-memory snapshot is not used and will just get garbage collected.

To change the jbo.txn.handleafterpostexc parameter, right click on your application module inside the application navigator, then select Configurations... from the pop-up menu, click the Edit button from the resulting dialog box and you are there.

Monday, 11 August 2008

Oracle Database : Space used in the flash recovery area

Here is a small script adopted from the book "RMAN Recipes for Oracle 11g" by Darl Kuhn, Sam R. Alapati and Arup Nanda. This script when run in from SQL Plus, will display the amount of used space in the current database flash recovery area.

SET PAGESIZE 66;
SET LINESIZE 80;

REPHEADER PAGE CENTER 'Flash Recovery Area Usage';

COLUMN FILE_TYPE FORMAT a20;
COLUMN FILE_TYPE HEADING 'File Type';

COLUMN USED_MB HEADING 'Used MBytes';
COLUMN USED_MB FORMAT 999999.99;
COLUMN RECLAIMABLE_MB HEADING 'Reclaimable Mbytes';
COLUMN RECLAIMABLE_MB FORMAT 9999999.99;

COLUMN NUMBER_OF_FILES HEADING 'Number of files';

BREAK ON REPORT
COMPUTE SUM LABEL 'Totals:' OF USED_MB RECLAIMABLE_MB ON REPORT;

SELECT
  rau.file_type,
  rfd.space_used * rau.percent_space_used / 1024 / 1024 as USED_MB,
  rfd.space_reclaimable * rau.percent_space_reclaimable / 1024 / 1024 as RECLAIMABLE_MB,
  rau.number_of_files as NUMBER_OF_FILES
FROM
  v$recovery_file_dest rfd, v$flash_recovery_area_usage rau;

Hre is a sample output run against a newly created 11g database

                            Flash Recovery Area Usage

File Type            Used MBytes Reclaimable Mbytes Number of files
-------------------- ----------- ------------------ ---------------
CONTROL FILE              716.17                .00               1
REDO LOG                11649.70                .00               3
ARCHIVED LOG            31957.11             391.11              10
BACKUP PIECE            79272.10                .00               2
IMAGE COPY                   .00                .00               0
FLASHBACK LOG                .00                .00               0
FOREIGN ARCHIVED LOG         .00                .00               0
                     ----------- ------------------
Totals:                123595.09             391.11

The concept is very simple. Oracle provides two views for retrieving information about the flash recovery area. One is the v$recovery_file_dest that contains information about the flash recovery area associated with the current database. A select * on this view will give us an output like the following :

SQL> select * from v$recovery_file_dest;

NAME
--------------------------------------------------------------------------------
SPACE_LIMIT SPACE_USED SPACE_RECLAIMABLE NUMBER_OF_FILES
----------- ---------- ----------------- ---------------
/u01/app/oracle/flash_recovery_area
 2147483648 1668797952          93845504              16

This view provides the total number of used and reclaimable bytes from the flash recovery area. The next view named v$flash_recovery_area_usage, provided percentage information about each type of file that can be stored in the flash recovery area. Doing a select * on this view gives up the following results.

SQL> set linesize 100;
SQL> select * from v$flash_recovery_area_usage

FILE_TYPE            PERCENT_SPACE_USED PERCENT_SPACE_RECLAIMABLE NUMBER_OF_FILES
-------------------- ------------------ ------------------------- ---------------
CONTROL FILE                        ,45                         0               1
REDO LOG                           7,32                         0               3
ARCHIVED LOG                      20,08                      4,37              10
BACKUP PIECE                      49,81                         0               2
IMAGE COPY                            0                         0               0
FLASHBACK LOG                         0                         0               0
FOREIGN ARCHIVED LOG                  0                         0               0

... so the next logical thing in order to get something meaningful out of these is to join them and this is what the initial script does. Since the v$recovery_file_dest view has only one column, all columns of the v$flash_recovery_area_usage view refer this hence the no need for a where clause in the script's sql.

Friday, 18 July 2008

Oracle ADF/ JSF: Mind your flags!

I do not know why JSF UI elements have a Disabled property. I mean I would prefer it if they instead offered an Enabled one. ADF bindings on the other hand have enabled properties, so UI tags usually look this :

<af:commandButton actionListener="#{bindings.Create.execute}"
                     text="#{res['commands.create']}"
                     disabled="#{!bindings.Create.enabled}"
                     action="addEdit"/>

How imagine having to wire in the UserInfo bean, I was talking about the other day. Ideally you would like to have the above Create button enabled when your user is an administrator i.e. #{UserInfo.admin == true} and when the Create binding is enabled, meaning #{bindings.Create.enabled == true}.

Since we now have a Disabled property, this means that the value assigned should be the opposite of #{UserInfo.admin == true && bindings.Create.enabled == true}. The EL expression for this is #{!(UserInfo.admin == true && bindings.Create.enabled == true)}. Using De Morgan's low we end up with #{!UserInfo.admin || !bindings.Create.enabled}.

I understand that for most people this is more than trivial, but I have to admit that is took me a good while to figure it out. (Does age come at a price or what?) I want to learn by my own mistakes. Therefore I thought I 'd put it down in witting, so I won't run into this again.

Tuesday, 15 July 2008

Oracle ADF: Viewlink based attributes vs Full Blown Queries

At one time or an other all of us must have dealt with an entity based View object whose SQL statement looked more or less like this :

SELECT UserInfo.USER_ID,
      UserInfo.USER_NAME,
      UserInfo.FULL_NAME,
      UserInfo.USER_ROLE,
      UserInfo.DEPARTMENT_ID,
      UserInfo.ACTIVE,
      Department.NAME,
      Department.ID
FROM USERS UserInfo, DEPARTMENTS Department
WHERE UserInfo.DEPARTMENT_ID = Department.ID (+)

This kind of VO may appear easy to create and manage when your schema contains two or three entities but things may end up pretty complicated as the number of associated entities increases. Let me show you the SQL statement of a view object displaying my version of the Service requests view in full detail.

  SELECT
      ServiceRequest.ID,
      ServiceRequest.REQUEST_DATE,
      TRUNC(REQUEST_DATE) AS SEARCH_DATE,
      ServiceRequest.REQUESTER_FIRST_NAME,
      upper( REQUESTER_FIRST_NAME) AS SEARCH_FIRST_NAME,
      ServiceRequest.REQUESTER_LAST_NAME,
      UPPER( REQUESTER_LAST_NAME) AS SEARCH_LAST_NAME,
      ServiceRequest.REQUESTER_TELEPHONE,
      ServiceRequest.LOCATION_STREET,
      ServiceRequest.LOCATION_NUMBER,
      ServiceRequest.LOCATION_AREA,
      ServiceRequest.LOCATION_ZIP,
      ServiceRequest.LOCATION_CITY,
      ServiceRequest.DEPARTMENT_FOR,
      Department.NAME AS DEPARTMENT_NAME,
      ServiceRequest.ASSIGNED_DATE,
      ServiceRequest.ASSIGNED_TO,
      AssignedTechnician.FULL_NAME AS TECHNICIAN_NAME,
      ServiceRequest.RESOLUTION_COMMENTS,
      ServiceRequest.REQUEST_STATUS,
      Status.NAME AS STATUS_NAME,
      ServiceRequest.PROBLEM_DESCRIPTION,
      AssignedTechnician.USER_ID,
      ServiceRequest.CREATED_BY,
      ServiceRequest.CREATED_ON,
      ServiceRequest.MODIFIED_BY,
      ServiceRequest.MODIFIED_ON,
      ServiceRequest.RESOLVED_ON,
      Department.ID AS ID1,
      Status.STATUS_ID,
      ServiceRequest.TELEPHONE_BY,
      TelephonedOperator.FULL_NAME AS TELEPHONE_OPERATOR_NAME,
      ServiceRequest.TELEPHONE_DATE,
      TelephonedOperator.USER_ID AS USER_ID1
 FROM
   SERVICE_REQUESTS ServiceRequest,
   DEPARTMENTS Department,
   STATUSES Status,
   USERS AssignedTechnician,
   USERS TelephonedOperator
 WHERE 
  (ServiceRequest.DEPARTMENT_FOR = Department.ID (+)) AND
  (ServiceRequest.REQUEST_STATUS = Status.STATUS_ID) AND
  (ServiceRequest.ASSIGNED_TO = AssignedTechnician.USER_ID(+)) AND
  (ServiceRequest.TELEPHONE_BY = TelephonedOperator.USER_ID(+))

When dealing with pure entity based view objects -- that is without a custom where clause -- then JDeveloper makes some descent effort in keeping your where clause straight. If you decide to add bind variables however, then JDeveloper completely looses it and you end up having to manage everything by hand. Where clauses have to be tampered with if you also decide that you need outer left joins and you cannot get away without using the primary keys of all the participating entities and then having to learn how to hide them.

I am never too happy when dealing with such monsters but users are always hungry for more and more information. I guess that this why every self respecting SAP table has at least 70 or more columns :-) ....

Anyway the thing that triggered my search for alternatives was the fact that on many occasions the reference fields of multi entity view objects would not update their values correctly especially after edits, until you issued a final commit, thus giving users one more reason to grumble. So instead of using the SQL query mode, I ended up using view link based transient attributes.

The idea is very simple. Create single entity based view objects containing all the relevant information. In our example Users and Departments. Then create a view link between the two and expose accessors to the client. Enable Java code generation for the primary view row. Last create a transient attribute to the source View (Users) that exposes the department name through the view link provided departments row member.

Let's follow the steps in more details....

For starters we can create two view objects UsersFullList and DepartmentsList with SQL statements like the following :

SELECT UserInfo.USER_ID,
      UserInfo.USER_NAME,
      UserInfo.FULL_NAME,
      UserInfo.USER_ROLE,
      UserInfo.DEPARTMENT_ID,
      UserInfo.ACTIVE
FROM USERS UserInfo

... for the Users View and ...

SELECT Department.ID,
      Department.NAME,
      Department.IS_TECH
FROM DEPARTMENTS Department

... for the departments. If you do not intend to edit Departments through your application, you may very well create a read only view object. Next we shall create a view link named UserAssignedToDept . Creating the view link is trivial, so I will show only you the images where we define the connection ....

and the view link properties :

The important thing to remember here is that since the view link cardinality is set to 1 → ∞ the department accessor will be of type Row instead of RowIterator. So if we next edit the UsersFullList view and create a Java class for the view row, then the code for the DepartmentInfo attribute will look exactly like this :

   /**Gets the associated Row using master-detail link DepartmentInfo
    */
   public Row getDepartmentInfo()
   {
       return (Row)getAttributeInternal(DEPARTMENTINFO);
   }

Creating a department name attribute for the the new view is now done by defining a transient attribute to the UsersFullList view

and then providing a getter method that looks like this :

   public String getDepartmentName()
   {
       String deptName;
       try {
           Row deptRow = this.getDepartmentInfo();
           deptName = (String )deptRow.getAttribute("Name");
       } catch (Exception e) {
           deptName = "";
       }
       return deptName;
   }

From the controller's side the view object looks exactly like it would if based on SQL and you don't have to hide the participating entity key attributes.

So is it worth it you might ask. The answer is -- as usually -- yes and no depending on the size of your project the complexity of your view objects and whether or not you prefer tampering with SQL code than Java. As I explained in the beginning of this posting the main advantage of this method is that your reference attributes will always display correctly since they are composed of pointers to the actual data of the view cache instead of cached entries. On the other hand if you project contains two view objects each composed from two entities, going through all that will be like killing a fly with a machine gun.

Friday, 11 July 2008

Oracle ADF: My simple UserInfo bean class

Some time ago, I posted a link to the JDeveloper forum regarding how to use he isUserInRole() method of the ExternalContext class in order to determine whether or not the current application user is assigned a role.

Since I have lost the original post, I am giving to display sample code showing how to reference the function, how to declare the bean in faces-config.xml and also how to use it.

Let's suppose that you our application has two roles. User and admin. Definitions ofr these roles is included in jazn-data.xml.

package mycompany.myapplication.view.beans;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

public class UserInfo {
   
    private boolean admin;
    private boolean user;

    public UserInfo()
    {
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ec = fc.getExternalContext();
        
        user = ec.isUserInRole("user");
        admin = ec.isUserInRole("admin");
    }
    
    public boolean isUser()
    {
        return user;
    }
    
    public boolean isAdmin()
    {
        return admin;
    }
}

The next step is to define the bean in faces-config.xml

  <managed-bean>
    <managed-bean-name>UserInfo</managed-bean-name>
    <managed-bean-class>mycompany.myapplication.view.beans.UserInfo</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>

Finally enabling or disabling a menu item property based on whether the user is an admin, is done like this

             <af:commandMenuItem text="#{res['menutabs.AdminAction']}"
                                    action="adminAction"
                                    disabled="#{!UserInfo.admin}"/>

By the same token preventing a page from being display is done like this

          <af:panelPage title="#{res['pages.pricelist.BasicFees.title']}"
                        rendered="#{UserInfo.admin}">

The truth of the matter is that I ended up using all that because I could not succeed in making j2ee security work for my application. Despite Chris Muir's hints on the JDeveloper forum, there was no way I could deny access to certain parts of my application, so I ended up enforcing security using my simple UserInfo bean that I hooked into the disabled and rendered properties of menu and panelPage tags of the protected pages like I showed before.

That way if anyone runs the application by going from the standard path, then he won't be able to access the admin pages and if he calls the pages directly, then he will see nothing.

Thursday, 3 July 2008

Oracl;e SQL Developer: Unable to dubug PL/SQL

I have to thank Brian from Oracle support for this one, but let me first give you the story.

If you are trying to debug PL/SQL using Oracle SQLDeveloper 1.5.1 and getting an like this :

then you are probably facing one of two options :

  • You are trying to access you database server from a machine getting its address from DHCP. In that case you will need to supply your ip address each time your start a debugging session. This is accomplished by checking the Prompt for Debugger Host for Database debugging checkbox in the Debuger page of the preferences dialog as shown in the image below.
  • The other option is that your machine firewall is blocking access to the debugging process between your machine and the DB server. In that case you need to reconfigure SQL Developer to use a speciffic port range and also have the firewall allow traffic through these ports.
    In my case all I had to do was change my debugger preferences so the dialog page looks exactly like this :

    and also change my firewall setup to allow access through port 4000.

One final comment. When I run into this problem and asked for help, deep inside I was already blaming my unsupported CentOS Linux version. I had already run into the same problem with my openSUSE machine and found no way out. As it turned out the solution was not machine or distro specific but rather platform independent. So next time, I promise to have a little more faith in my own devices,

Now SQLDeveloper 1.5.1 runs very nicely on both machines at home and at work, and me having regained my trust on the platform, I even run it using the 64 bit 1.6.0_06 JDK. To be honest I haven't seen any real changes in terms of speed, but I tell myself that now I can savour one more taste of the 64 bit glamour. ;-)

Thanks again Brian.

Wednesday, 2 July 2008

PHP: Number of rows from query

The idea comes from the developers of Oracle ADF, I have seen it work on JDeveloper and I thought that I can use it in PHP. The trick here is to place the entire query inside a SELECT count(*) from ($query) statement.

Once you know what to do implementation is as easy as witting the code below. The only comment is that the function references an already initialized external mysqli class variable that connects to the database, which if you feel like it may also be passed as a function parameter.

    /**
      * returns the number of records  of the query passed as parameter 
      */
    function numRecordsOfQuery( $a_query) 
    {
        global $mysqli;

        $count_query = " 
                   SELECT count(*) as TotalLines 
                     FROM ($a_query) MyQuery";
        $result = $mysqli->query($count_query);
        // echo $count_query;
        $row = $result->fetch_array( MYSQLI_ASSOC);
        $numRecords = $row['TotalLines'];
        $result->close();
        
        return $numRecords;
    }

Note The MyQuery references is mandatory. MySQL will return an error if the enclosed query is not referenced.

Wednesday, 18 June 2008

CentOS: Manual install of plugins for Mozilla Firefox

This is just a note to myself and everyone else in the same spot.

Flash Player

Manual installation of the Flash player plugin for a new Firefox installation is done like this :

[root@lxbakalidis ~]# cd /opt/mozilla/firefox/plugins
[root@lxbakalidis plugins]# ln -sf /usr/lib/flash-plugin/libflashplayer.so 
libflashplayer.so

Detailed instructions for installing flash-player from Adobe are available here.

Java

The java plugin gets installed by linking libjavaplugin_oji.so located in $JAVA_HOME/jre/plugin/i386/ns7/ in your plugin dir.

Real Player

For real Player the plugin name is nphelix.so and the plugin location is /opt/RealPlayer//mozilla/.

Friday, 30 May 2008

Oracle ADF: Enriching the actions of a ViewObject

Based on the technique described two posts back regarding creation of a custom ViewObject that offers ready to drag actions, I now give you another simple yet very handy function. The showAllRows() function when added to the AB_BaseViewObject methods, allows you to create a button in a search page that removes all view criteria and executes the current query, very useful for cases when uses enter lots of view criteria and then need to display the entire contents of the entire row with a single click.

    public void showAllRows()
    {
        clearViewCriterias();
        executeQuery();
    }

Remember that in order for the action to appear in the JDeveloper Data Control Palette like in the following picture, you must include the showAllRows() function to the view objects client interface.