Showing posts with label ADF. Show all posts
Showing posts with label ADF. Show all posts

May 13, 2017

ADF και EJB timers

Είναι εξαιρετικά εύκολο να χρονοπρογραμματίσουμε την εκτέλεση μιας ADF BC μεθόδου χρησιμοποιώντας EJB timers. Ας ξεκινήσουμε με την υλοποίηση των μεθόδων σε ένα Application Module τις οποίες ορίζουμε στο client interface. Στο παράδειγμα μας δυο μέθοδοι, exportData και uploadData που εκτελούνται σε τακτικά χρονικά διαστήματα.
Σε ένα νέο JDeveloper project (πχ ονόματι tasks) ενσωματώνουμε τις κατάλληλες maven εξαρτήσεις για τo JEE και το ADF όπως:

  <dependency>
      <groupId>com.oracle.adf.library</groupId>
      <artifactId>Java-EE</artifactId>
      <version>12.2.1-1-0</version>
      <type>pom</type>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.oracle.adf.library</groupId>
      <artifactId>EJB</artifactId>
      <version>12.2.1-1-0</version>
      <type>pom</type>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.oracle.adf.library</groupId>
      <artifactId>ADF-Common-Runtime</artifactId>
      <version>12.2.1-1-0</version>
      <type>pom</type>
      <scope>provided</scope>
    </dependency>

Απαραίτητο είναι επίσης να ορίσουμε και το maven dependency για το model project μας. Φτιάχνουμε τώρα μια java κλάση που καλεί την διαδικασία exportData. Χρησιμοποιούμε το Schedule annotation για τον χρονοπρογραμματισμό ενώ κάνουμε μια απλή σύνδεση στο Application module για να καλέσουμε την μέθοδο που θέλουμε από το client interface.

Το παράδειγμα δοκιμάστηκε σε JDeveloper 12.2.1.1.0.

Apr 21, 2017

Συμβουλές για JMeter και ADF 12c

O καλύτερος τρόπος να ξεκινήσει κανείς σενάρια performance testing με το JMeter σε εφαρμογές ADF, είναι να χρησιμοποιήσει το test plan από εδώ, να το διαμορφώσει σε ένα test fragment και να το αξιοποιήσει σε περαιτέρω πλάνα. Επιπλέον συμβουλές που δοκιμάστηκαν σε ADF 12.2.1.2.0 :


  • Όπως αναφέρεται και στο soadev blog ο resolver για το _afrLoop έχει την μορφή: _afrLoop',\s*'([0-9]{13,16})
  • Για πιο αποτελεσματικό recording ADF εφαρμογών μπορούμε να παραλείψουμε αρχεία css, png και js διαμορφώνοντας κατάλληλα τον script recorder
  • Για την καλύτερη οργάνωση των HTTP requests που γίνονται record, είναι προτιμότερο να τα οργανώσουμε ανά transaction controller

  • Τέλος, στη λίστα των patterns to test, ας προσθέσουμε το "Because of inactivity..." επειδή είναι ένα πολύ πιθανό μήνυμα όταν δεν έχει διαμορφωθεί σωστά το σενάριο



Jan 8, 2017

Oracle Fusion Middleware RCU στο Amazon cloud (AWS)

To AWS προσφέρει την υποστήριξη της Oracle Database (Oracle RDS) με παρεχόμενες άδειες και με ειδικά γνωρίσματα όπως:

  • δίνεται λογαριασμός με DBA privileges αλλά δεν παρέχεται πρόσβαση στα SYS και SYSTEM accounts
  • δεν προσφέρεται SSH πρόσβαση στους database servers
  • υποστηρίζονται μόνο Oracle Managed Files (OMF) για datafiles
Περισσότερες πληροφορίες εδώ και εδώ.

Μέσω του Ansible, όταν έτρεξα το RCU για ένα 12.2.1.1.0 domain διόρθωσα ώστε το script ώστε ο database user να μην έχει SYSDBA δικαιώματα (normal user), αλλά πήρα το ακόλουθο λάθος ORA-20900: RDS only supports Oracle Managed Files.

Έχουμε δυο επιλογές:

  • στο RCU script μας παιρνάμε την παράμετρο honorOMF που κατασκευάζει τα datafiles συμβατά με OMF
  • κατασκευάζουμε τα tablespaces μόνοι μας και ξανατρέχουμε το RCU
Πέρα από αυτό, δεν αντιμετώπισα κανένα άλλο πρόβλημα στο να τρέξω μια 12.2.1.1.0 ADF εφαρμογή στο AWS χρησιμοποιώντας είτε Oracle RDS 11.2.0.4 είτε το 12.1.0.2.

Mar 29, 2015

Παρακολούθηση απόδοσης ADF εφαρμογών με το XRebel

Όταν η παρακολούθηση της απόδοσης (performance) μιας εφαρμογής αποτελεί τμήμα της καθημερινής διαδικασίας ανάπτυξης (development process), τότε μπορούμε να φτιάχνουμε καλύτερο λογισμικό και να περιορίσουμε δυσάρεστες εκπλήξεις στην παράδοση σε ένα παραγωγικό σύστημα. Αν και αυτό θα έπρεπε να ισχύει για κάθε περίπτωση, ιδίως για τις εφαρμογές που βασίζονται στο Oracle ADF αποκτά ιδιαίτερη αξία, καθώς αποτελεί ένα database-oriented framework και συχνά προβλήματα απόδοσης προέρχονται από το επίπεδο της βάσης δεδομένων. Γι' αυτό ακριβώς το λόγο, βρήκα εξαιρετικά χρήσιμο το εργαλείο XRebel που κατά τη διάρκεια της εκτέλεσης μιας web εφαρμογής μας εμφανίζει άμεσα, σε ένα widget ενσωματωμένο στην σελίδα μας, πληροφορίες για τα SQL statements που εκτελούνται, τους χρόνους τους καθώς και την επιβάρυνση του web session.

Δοκίμασα λοιπόν την τελευταία έκδοση του XRebel (2.0 Beta) σε μια εφαρμογή φτιαγμένη με το UI shell (dynamic tabs) Ευτυχώς, η ZeroTurnaround (εταιρεία που κατασκευάζει το XRebel) προσέφερε μια δοκιμαστική έκδοση 30 ημερών μέσα στον Μάρτιο 2015. Έπειτα από το download, η ενεργοποίηση του XRebel γίνεται στο Run Configuration του JDeveloper, με την προσθήκη του java agent για το xrebel.jar.
Έπειδή το XRebel θα ενσωματωθεί στο runtime της εφαρμογής μας, καλό θα είναι να αυξήσουμε το heap size του Weblogic (τουλάχιστον -Xmx=1024m) Ξεκινούμε την εφαρμογή όπως γνωρίζουμε. Με την εκκίνηση λοιπόν, θα εμφανιστεί το widget που XRebel. Εκεί εμφανίζεται:

  1. profiling πληροφορία του κώδικα μας (ποια σημεία αργούν πιο πολύ στην εκτέλεση)
  2. Database operations (queries και SQL statements) που εκτελούνται στην οθόνη μας
  3. Το πόσα και ποια objects βρίσκονται στο user session και ποιά είναι η επιβάρυνση τους στην μνήμη του Weblogic
Αν για παράδειγμα κάνουμε κλικ για περισσότερες πληροφορίες για τα database operations, θα εμφανιστεί ένα popup που αναλύονται όλα τα SQL statements, ποιούς πίνακες αφορούν, πόσε εγγραφές επιστρέφονται και πόσο χρόνο πήρε η εκτέλεσή τους. Εντυπωσιακό ! Στην παραμετροποίηση του XRebel μπορούμε να ορίσουμε threshold values για τα timings των SQL queries ή τον αριθμό τους.
Κάτι που λείπει είναι η άθροιση των SQL statements ώστε να διαπιστώσουμε επαναλαμβανόμενες SQL εντολές. Τα απολέσματα του XRebel μπορούν να κατευθυνθούν σε αρχείο (διαδρομή $HOME/.xrebel/xrebel.log στο Linux) ώστε να κάνουμε εκεί analytics. Να και μια φωτογραφία από το application profiling.
Η βοήθεια που μου έδωσε το XRebel ήταν ανεκτίμητη. Με εύκολο, γρήγορο και γραφικό τρόπο μου έδωσε πληροφορίες απόδοσης της εφαρμογής και με βοήθησε να βελτιώσω κάποια SQL queries και να διορθώσω κάποια bindings, χωρίς να κοιτάξω σε πολλαπλά log files. Το συνιστώ ανεπιφύλακτα !

Mar 23, 2015

Κεντρικός oρισμός application module και connection pooling παραμέτρων για το ADF BC

Παραμέτρους σχετικά με το application module pooling στο ADF μπορούμε φυσικά να δηλώσουμε ως τμήμα του εκάστοτε application module configuration. Σε περίπτωση που θέλουμε να θέσουμε τιμές σε αυτές τις μεταβλητές, για όλα τα modules του έργου μας, τότε αναγκαστικά είτε θα έχουμε μεγάλη πειθαρχία (και εκτέλεση audit rules) από την ομάδα μας, είτε θα αφήσουμε αυτή την λειτουργία ως τμήμα των deployment scripts.
Ευτυχώς το ADF μας επιτρέπει να κεντρικοποιήσουμε όλες αυτές τις μεταβλητές σε ένα σημείο, και αν θέλουμε, να ορίσουμε ειδικές τιμές ανά περίπτωση. Δεν έχουμε λοιπόν παρά να καταφύγουμε στο αρχείο adf-config.xml. Παρόλο που ο visual editor δεν μας δείχνει πως υπάρχει η δυνατότητα επηρεασμού του ADF BC παρά μόνο για πολύ λίγες παραμέτρους (πχ locking mode, failover, fetch size) αν ανατρέξουμε στον πηγαίο κώδικα (source code) έχουμε περισσότερες επιλογές.
Εκεί μπορούμε να ορίσουμε στην ενότητα "amconfig-defaults" τις τιμές για παράδειγμα για το connection pooling, ή οποιαδήποτε άλλη παράμετρο του application module configuration.
Μετά την αλλαγή, αν ανατρέξουμε σε οποιοδήποτε application module μας θα δούμε άμεσα αυτές τις ρυθμίσεις. Η δοκιμή έγινε στον JDeveloper 12.1.3 και δεν είμαι σίγουρος αν ισχύει κάτι ανάλογο και για προηγούμενες εκδόσεις.

Feb 15, 2015

Maven και Docker: περισσότερα από την Oracle σε λίγο

H Oracle δεν είναι από τις εταιρείες της κατηγορίας early technology adopters. Προκειμένου να ενσωματώσει τεχνολογίες στα προϊόντα θα περάσει κάποιος καιρός...Ένα τυπικό παράδειγμα είναι η υιοθέτηση του Maven ως build tool για το Oracle Fusion Middleware, γεγονός που εγκαινιάστηκε με την 12c εντός του 2014, ενώ όλος ο υπόλοιπος κόσμος εδώ και χρόνια έχει στραφεί σε αυτήν την λύση. Υπάρχουν λοιπόν τουλάχιστον δυο κατευθύνσεις που φαίνεται πως η Oracle θα επενδύσει περισσότερο στο αμέσως επόμενο διάστημα: το πρώτο έχει να κάνει με το Maven, το δεύτερο με τους docker containers.

Σε αυτό το άρθρο ας ασχοληθούμε με το Maven. Επιτέλους με την 12c παρουσιάστηκαν πολλά νέα σημαντικά χαρακτηριστικά όπως:

  1. επίσημη τεκμηρίωση για Continuous Integration του Oracle Fusion Middleware με την βοήθεια του Maven
  2. διαρκώς καλύτερη υποστήριξη στον JDeveloper για Maven (ιδίως στην έκδοση 12.1.3)
  3. Δημιουργία του Oracle Maven repository που έγινε διαθέσιμο μόλις πριν ένα μήνα περίπου για υποστήριξη ADF και SOA εφαρμογών. H αλήθεια είναι πως ζηλέψαμε πολύ τον Maven browser του NetBeans, έτσι όπως βλέπει αυτό το repository !!
  1. (εκτός Oracle): υποστήριξη του Oracle Maven repository από το Artifactory
  2. διαρκής ανάπτυξη του Maven Weblogic development plugin (για δημιουργία Weblogic domains) καθώς και του Weblogic deployment plugin
Αναμένουμε στην επόμενη έκδοση του Oracle Fusion Middleware να δούμε περισσότερα χαρακτηριστικά αλλά και διορθώσεις όπως:
- ενδεχόμενη αντικατάσταση του Maven sync plugin για τις ADF/SOA βιβλιοθήκες στον JDeveloper, από την στιγμή που υπάρχει το Oracle Maven repository.
- καλύτερη υποστήριξη μέσα στον JDeveloper της επεξεργασίας POM αρχείων. Στην έκδοση 12.1.3, τουλάχιστον η επεξεργασία ενός POM όταν υπάρχει μόνο το local repository καθυστερεί απελπιστικά.
- καλύτερη διασύνδεση με τα project files (.jpr) του JDeveloper: όταν ενημερώνεται ένα POM αυτό συνεπάγεται και την ενημέρωση των JDeveloper project metadata (και αντίστροφα) για την δήλωση των βιβλιοθηκών που ενσωματώνονται. Αυτή η ενημέρωση δεν είναι πάντα σωστή και έχω δει πολλές φορές "σκουπίδια" μέσα στα jpr metadata, αποσυγχρονισμούς αλλά προβλήματα μεταξύ Linux και Windows workstations: για παράδειγμα το Linux μου έγραφε στο .jpr δηλώσεις βιβιοθηκών όπως:

  <url protocol="file" path="${maven:maven.local.repo}com/mylib/1.0.0-SNAPSHOT/mylib-1.0.0-SNAPSHOT.jar"/>  

η ίδια βιβλιοθήκη δεν μπορούσε να διαβαστεί από τα Windows παρά μόνο αν γινόταν προσθήκη του slash '/' στο path

  <url protocol="file" path="/${maven:maven.local.repo}com/mylib/1.0.0-SNAPSHOT/mylib-1.0.0-SNAPSHOT.jar"/>  



Nov 19, 2014

Αποστολή γεγονότων (dispatching events) σε πολλαπλά ADF task flow managed beans

Μια πολύ σημαντική αρχή του αντικειμενοστραφούς προγραμματισμού είναι ο περιορισμός του κεντρικού ελέγχου διαδικασιών και η κατανεμημένη διανομή γεγονότων (events) όπου υπάρχει ενδιαφέρον. Στον κόσμο του ADF, ένα αντιπαράδειγμα που  έρχεται στο μυαλό έχει να κάνει με μεγάλους κώδικες που συντηρούνται σε ADF managed beans και που επιτελούν διαφορετικές λειτουργίες, καλύπτοντας πολλαπλές διαφορετικές απαιτήσεις.

Έστω πως θέλουμε να δώσουμε μια κοινή συμπεριφορά στην εφαρμογή μας ώστε με ένα κουμπί να γίνεται αποθήκευση (commit) των αλλαγών. Επιπλέον, θα θέλαμε να εμφανίζεται ένα popup παράθυρο επιβεβαίωσης μετά την οριστικοποίηση. Τέλος με την ολοκλήρωση των αλλαγών θέλουμε να ενημερώνεται η κατάσταση του TabContext αν χρησιμοποιούμε το Dynamic Tabs UI Shell framework. Θα φτιάξουμε σε ένα σημείο μια συγκεντρωτική λειτουργία που θα καλύπτει όλες τις παραπάνω ανάγκες;

Μια προσέγγιση θα μπορούσε να κάνει με την υλοποίηση της διαδικασίας της αποθήκευσης και την ειδοποίηση άλλων ενδιαφερόμενων αντικειμένων για αυτήν την μεταβολή, ώστε να κάνουν αυτά τη δουλειά τους (να προβάλλουν popup, να μεταφέρουν τον χρήστη σε άλλη οθόνη, να ενημερώσουν το UI shell, κλπ) Ευτυχώς μπορούμε να ορίσουμε μια λίστα από κλάσεις που σχετίζονται με ένα ADF managed bean στον ορισμό του task flow, ώστε αυτή η λίστα να ενημερώνεται για μια μεταβολή. Ας κατασκευάσουμε για παράδειγμα ένα Java interface:

public interface CommitListener {
    void afterCommit();
}

και αντίστοιχα δυο κλάσεις που το υλοποιούν: έστω τη JSFCommitListener που εμφανίζει ένα popup και την DynamicTabListener που ενημερώνει το UI Shell. Τις δυο αυτές κλάσεις ας τις ορίσουμε στο task flow μας:
ενώ στην κλάση μας που διαχειρίζεται το κουμπί της αποθήκευσης των αλλαγών (πχ CommitBean), ας δηλώσουμε μια γενική λίστα από κλάσεις που θα πρέπει να ενημερωθούν:

    private List commitListeners;

    public void setCommitListeners(List<CommitListener> observers) {
        this.observers = observers;
    }

    public List getCommitListeners() {
        return observers;
    }

    public void onCommit() {
            for (CommitListener c : getCommitListeners()) {
                c.afterCommit();
            }
    }

Αυτό που μας απομένει είναι να κάνουμε ενσωματώσουμε (inject) τη λίστα των managed beans (listeners) στην κλάση μας CommitBean. Επιστρέφουμε λοιπόν στο task flow μας και γράφουμε τον ακόλουθο κώδικα (μιας και δεν υπάρχει υποστήριξη στον design editor για την παροχή λίστας τιμών):

<managed-bean>
    <managed-bean-name>commitBean</managed-bean-name>
    <managed-bean-class>CommitBean</managed-bean-class>
    <managed-bean-scope>backingBean</managed-bean-scope>
    <managed-property>
      <property-name>commitListeners</property-name>
      <list-entries>
            <value>#{backingBeanScope.dynamictablistener}</value>
            <value>#{backingBeanScope.jsfcommitlistener}</value>
        </list-entries>
    </managed-property>
  </managed-bean>



Oct 5, 2014

Δυο χαρακτηριστικά του JSF 2 που είναι χρήσιμα στο ADF

Η 12c σειρά του JDeveloper (αλλά και η παλαιότερη 11g R2) υποστηρίζουν το πρότυπο JSF 2. Ανάμεσα στα πολλά νέα χαρακτηριστικά που έχει αυτή η έκδοση, σε σχέση με την 1.2, θα ήθελα να αναφέρω δυο γνωρίσματα που ίσως να φανούν χρήσιμα στους προγραμματιστές του Oracle ADF.

Το πρώτο έχει να κάνει με το ότι οι action μέθοδοι των navigation components (buttons, menus, links) επιδέχονται ορίσματα. Ενώ μέχρι το JSF 1.2 το managed bean action method signature δεν δέχονταν παραμέτρους, στο JSF 2 μπορούν να δεχτούν ορίσματα οποιουδήποτε τύπου. Ένα παράδειγμα χρήσης έχει να κάνει με το πέρασμα ως παραμέτρου της τιμής ενός attribute binding ή selected row(s) για το οποίο θα θέλαμε είτε UI components bindings είτε ADF bindings κώδικα στο managed bean μας. Στο παρακάτω απόσπασμα κώδικα, η managed bean action method χρησιμοποιεί ως παράμετρο την επιλεγμένη εγγραφή του πίνακα.
Ο δε κώδικας του managed bean μοιάζει ως εξής. Οι επιλεγμένες είναι άμεσα διαθέσιμες μέσω της κλάσης RowKeySet.

Το δεύτερο, αφορά την υλοποίηση συμπεριφοράς όταν συμβαίνουν συστεμικές ενέργειες (system events) σε UI components. Τέτοιες ενέργειες μπορούν να περιλαμβάνουν για παράδειγμα την αρχική εμφάνιση ενός στοιχείου (pre-render) σε μια σελίδα (περισσότερες πληροφορίες εδώ) Κάτι τέτοιο μπορεί να μας είναι πολύ χρήσιμο ώστε να υλοποιήσουμε λογικές τύπου "on component ή page load". Μάλιστα υπάρχει ένα παράδειγμα του ADF code corner για την προβολή ενός pop-up με την αρχική εμφάνιση ενός region. Έστω ότι θέλουμε να επηρεάσουμε το αρχικό rendering ενός πίνακα, ώστε εμφανίσουμε εξ ορισμού μια επιλεγμένη εγγραφή. Τότε μπορούμε να χρησιμοποιήσουμε το JSF component f:event, ενσωματωμένο στο component που μας ενδιαφέρει, στην περίπτωση μας ένα af:table.
 
H ιδιότητα listener μας ανοίγει το δρόμο για να προγραμματίσουμε τη συμπεριφορά του pre-render. Έτσι μπορούμε να κάνουμε μια προγραμματιστική αντιμετώπιση του event, χωρίς να καταφύγουμε σε σύνθετους κώδικες και phase listeners όπως συνέβαινε με προηγούμενες εκδόσεις.

    public void preRender(ComponentSystemEvent componentSystemEvent) {
        UIComponent tab = componentSystemEvent.getComponent();
    }

Jun 4, 2014

Σύντομος και ασφαλής υπολογισμός ενός inline if της Groovy στο ADF

Στο ADF μπορούμε σε πολλαπλά σημεία να χρησιμοποιήσουμε εκφράσεις της Groovy για διάφορες λειτουργίες. Ειδικά ως προς τους υπολογισμούς συχνά πρέπει να ελέγχουμε αν υπάρχει σωστή αρχικοποίηση τιμών ώστε να αποφύγουμε τιμές όπως null. Ευτυχώς στην Groovy υπάρχει μια βελτίωση του inline if ώστε να καλύπτεται με συντομία και ασφάλεια η απουσία τιμής. Για παράδειγμα στο σχήμα fod, ο υπολογισμός ενός πεδίου LineTotal που προκύπτει από δυο άλλα (UnitPrice και Quanity) μπορεί να οριστεί ως:

(Quantity ?: 0) * (UnitPrice ?: 0)

Nov 21, 2013

Στατική ανάλυση σε έργα SOA και BPEL με τη βοήθεια ενός XML repository

Έχω αναφερθεί στο παρελθόν (εδώ και εδώ) στις δυνατότητες εξαγωγής χρήσιμης γνώσης από την στατική ανάλυση (static code analysis) των XML metadata στα οποία στηρίζονται frameworks όπως το Oracle ADF. Η ιδέα που είχε τότε περιγραφεί ήταν της μεταφοράς αυτής της δομής σε μια σχεσιακή βάση δεδομένων ώστε να τίθενται με άνεση διάφορα, συνδυαστικά ερωτήματα.

Αυτό το χρονικό διάστημα συνεργάζομαι με μια έμπειρη ομάδα σε ένα έργο βασισμένο στο Oracle SOA Suite, με το μεγαλύτερο μέρος του γραμμένο σε BPEL. Περιλαμβάνει πολλές, σύνθετες διαδικασίες και ως νεο-εισερχόμενος αναζητώ τρόπους γρηγορότερης, γενικότερης και πιο εποπτικής κάλυψης του αντικειμένου. Δεδομένου ότι τόσο μια διαδικασία BPEL, όσο και ο ορισμός ενός SCA composite περιγράφονται σε XML, μου κίνησε ξανά το ενδιαφέρον της στατικής ανάλυσης. Αυτή τη φορά διάλεξα ένα άλλο δρόμο ως repository των XML metadata: την φόρτωση τους απευθείας σε μια XML database και την κατασκευή ερωτημάτων με την χρήση των αντίστοιχων τεχνολογιών (XPath και XQuery)

Ως XML database, διάλεξα το BaseX που μου φάνηκε εξαιρετικά απλό στην χρήση του. Πρόκειται για μια Java εφαρμογή, πολύ φιλική στην χρήση της, με υποστήριξη για XQuery 3.0. Έχοντας λοιπόν σε έναν κατάλογο όλους τους πηγαίους κώδικες (SCA composites, BPEL processes, JCA adapters configurations, κλπ) έφτιαξα μια νέα βάση δεδομένων.
Από την στιγμή που τελειώσει το φόρτωμα και το indexing των αρχείων, παρουσιάζεται το BaseX interface. Στο αριστερό πλαίσιο μπορούμε να υποβάλλουμε τις ερωτήσεις μας (full-text, XQuery) στο δεξί πάνω πλαίσιο εμφανίζονται οπτικά τα "ταιριάσματα" σε αρχεία, ενώ στο κάτω μέρος εμφανίζονται τα περιεχόμενα του matching καθώς και τα στατιστικά εκτέλεσης.
 Έχοντας πια όλα τα έγγραφα σε μια βάση στη διάθεσή μας, μπορούμε να κατασκευάσουμε σύνθετα ερωτήματα. Για παράδειγμα θέλοντας να κατατάξουμε τις BPEL διαδικασίες μας από άποψη πολυπλοκότητας, μπορούμε να δούμε πόσες διακλαδώσεις (branching) περιλαμβάνουν, πόσες κλήσεις (invokes), κλπ. Ένα τέτοιο Xquery ερώτημα είναι το ακόλουθο:

declare default element namespace "http://schemas.xmlsoap.org/ws/2003/03/business-process/";
for $f in collection()
let $name := document-uri($f)
let $doc := doc($name)
let $nproc := count($doc//process)
let $pname := $doc/process/@name
let $ninvoke := count($doc//invoke)
let $npick := count($doc//pick)
let $nwhile := count($doc//while)
let $nswitch := count($doc//switch)
let $nflow := count($doc//flow)
let $nl := " "
where $nproc > 0
return
  $pname || ' I=' || $ninvoke || ' P=' || $npick || ' W=' || $nwhile || ' S=' || $nswitch || ' F=' || $nflow || $nl


Μια άλλη περίπτωση έχει να κάνει με την εύρεση αχρησιμοποίητων μεταβλητών. Ένα ενδεικτικό ερώτημα, που τυπώνει τον αριθμό των χρησιμοποιήσεων μιας μεταβλητής σε μια BPEL διαδικασία:

declare default element namespace "http://schemas.xmlsoap.org/ws/2003/03/business-process/";
for $f in collection()
let $name := document-uri($f)
let $doc := doc($name)
let $nproc := count($doc//process)
let $pname := $doc/process/@name
let $nl := " "
for $var in distinct-values(doc(document-uri($f))//variable/@name)
let $nv := count(//receive[@variable=$var]) + count(//from[@variable=$var]) + count(//to[@variable=$var]) + count(//invoke[@inputVariable=$var]) +  count(//receive[@variable=$var]) + count(//onMessage[@variable=$var]) +  count(//from/@expression[contains(., $var)]/text()) + count(//catch[@faultVariable=$var])
order by $pname,$var
return $pname || ':' || $var || ':' || $nv || $nl


Εν ολίγοις, το BaseX προσφέρει μια πολύ καλή λύση για αναλυτικές εργασίες σε XML αυτού του είδους, ενώ φυσικά τα οφέλη της στατικής ανάλυσης κώδικα είναι απεριόριστα, ιδίως για την διακυβέρνηση μεγάλων έργων.

Jul 13, 2013

Καλύτερη οργάνωση application roles στο ADF

Οι εφαρμογές που αναπτύσσουμε στο ADF είναι δυνατόν να απαιτούν την ύπαρξη δεκάδων ρόλων. Ενδεχομένως, να χρειάζεται να αναθέσουμε δικαιώματα ανά use case ή μάλλον καλύτερα ADF task flow. Σε μια τέτοια περίπτωση, είναι χρήσιμο να οργανώσουμε τους ρόλους μας σε κατηγορίες.

Στην έκδοση JDeveloper 11.1.1.6, κατά τη διάρκεια επεξεργασίας του πλαισίου ασφάλειας μιας εφαρμογής, μπορούμε να προσθέσουμε μια νέα κατηγορία ρόλων (role category) Στην νέα κατηγορία μπορούμε να προσθέσουμε υφιστάμενους ρόλους ή καινούργιους που θα κατασκευάσουμε. Έτσι θα μπορούμε να βλέπουμε πιο οργανωμένα, τους ρόλους ασφάλειας, ενώ επιτρέπεται μόνο το πρώτο επίπεδο ομαδοποίησης. Αυτή η κατηγοριοποίηση δεν έχει κανένα άλλο αποτέλεσμα πέρα από αυτό της (οπτικής) οργάνωσης. Δηλαδή δεν επιτρέπει να γίνεται ανάθεση δικαιωμάτων ή άλλων ρόλων σε επίπεδο κατηγορίας.

May 31, 2013

Ένα βιβλίο για όσους ξεκινούν στο Oracle ADF (Oracle ADF 11gR2 Development Beginner's Guide)

Η τελευταία κριτική μου για βιβλίο σχετικό με το ADF ήταν πριν περίπου έξι μήνες. Κοιτάζοντας πίσω στο χρόνο φαίνεται πως περίπου κάθε εξάμηνο τα τελευταία 2-3 χρόνια έχουμε μια νέα κυκλοφορία σχετικά με το ADF είτε από την Packt είτε από την Oracle Press. Ενώ όμως αφθονούν οι τίτλοι για προχωρημένα θέματα ή μεθοδολογίες στο ADF, αυτό που επίσης χρειάζεται είναι ένας οδηγός για αυτούς που ξεκινούν τώρα με το framework, μιας και το επίσημο documentation της Oracle (developer's guide) μάλλον δεν είναι πολύ φιλικό για μια πρώτη επαφή. Χρειάζονται βιβλία λοιπόν που να εξηγούν με απλά λόγια και παραδείγματα το πώς λειτουργεί το ADF, ώστε διαβάζοντας το κάποιος "πρωτάρης" σε μικρό χρονικό διάστημα να προσανατολιστεί πάνω στο framework. Ένα αντίστοιχο βιβλίο, και μάλιστα πολύ καλό για την εισαγωγή στον προγραμματισμό στο ADF είναι το "Quick start Oracle Fusion Development" του Grant Ronald.

Πρόσφατα, κυκλοφόρησε και το "Oracle ADF 11gR2 Development Beginner's Guide", με συγγραφέα τον Vinod Krishnan, από την Packt Publishing που απευθύνεται σε τεχνικούς που κάνουν την πρώτη τους γνωριμία με το ADF, χωρίς να απαιτούνται ειδικές γνώσεις, πέρα από τις βασικές του προγραμματισμού σε Java. Ο ρυθμός που είναι καλός, είναι πλούσιο σε παραδείγματα και screenshots, αλλά υπάρχουν και φορές που καταπιάνεται με ειδική τεχνική λεπτομέρεια, που δεν είναι ίσως απαραίτητη ή χρήσιμη σε κάποιον που κάνει τα πρώτα βήματα του στο ADF. Η δομή του βιβλίου είναι ως εξής: περιλαμβάνει έντεκα κεφάλαια. Τα θέματα αναπτύσσονται με την μορφή: περιγραφή του ζητήματος, εκτέλεση της διαδικασίας (time for action), επεξήγηση του πώς δουλεύει η λύση (what just happened ?) και πρόκληση στον αναγνώστη για περαιτέρω εξερεύνηση στην ενότητα "Have a go hero". Τέλος, κάθε κεφάλαιο κλείνει με την μορφή ανακεφαλαιωτικό ερωτήσεων (quiz) Ας δούμε λοιπόν την ύλη του σε λεπτομέρεια.

Το πρώτο κεφάλαιο ("Installing and Configuring JDeveloper IDE") αφιερώνεται στην εγκατάσταση και λειτουργία του JDeveloper, στα μενού, τα παράθυρα, τους συντάκτες κειμένου που διαθέτει και την εν γένει "φιλοσοφία" του. Είναι πραγματικά πολύ κατατοπιστικό και χρήσιμο για κάποιον που προέρχεται από κάποιο άλλο IDE (πχ Eclipse ή Oracle Forms) ώστε να μπορέσει γρήγορα να εξοικειωθεί και να γίνει παραγωγικός, κάτι που φυσικά θέλει τον χρόνο του. Το δεύτερο κεφάλαιο ("Getting Started with ADF") εξηγεί σε βασικές γραμμές την αρχιτεκτονική του ADF και αναλύει, από την αρχή ως το τέλος, ένα παράδειγμα ανάπτυξης μιας μικρής εφαρμογής σε ADF, με πολύ αναλυτικά βήματα και screenshots. Το κεφάλαιο τρία ("Understanding the Model Layer") εστιάζει στα ADF Business Components (entities, view objects, application modules) και διαθέτει έναν πολύ αναλυτικό οδηγό για τις επιλογές στις οθόνες παραμετροποίησης του ADF (declarative programming) Το αμέσως επόμενο κεφάλαιο ("Validating and Using the Model Data") δίνει παραδείγματα validations με δηλωτικά χαρακτηριστικά και με Groovy expressions και στο δεύτερο μισό του αναφέρεται στον επηρεασμό της συμπεριφοράς του framework με την χρήση Java καθώς και στον χειρισμό των transactions. Είναι ένα πολύ σημαντικό κεφάλαιο, που ίσως να χρειάζεται περισσότερη απλοποίηση στην περιγραφή.

Το κεφάλαιο πέντε ("Binding the Data") είναι πραγματικά ένα θαυμάσιο κεφάλαιο γιατί επεξηγεί με ακρίβεια και λεπτομέρεια τον μηχανισμό των data bindings που είναι από τα πιο παράξενα πράγματα για έναν newcomer στον κόσμο του ADF. Το επόμενο κεφάλαιο μας εισάγει στο web programming με τα ADF Faces κάνοντας χρήση templates και δίνοντας μια σύντομη παράθεση των user interface components και των ιδιοτήτων τους. Αισίως, το κεφάλαιο επτά ("Working with navigation flows") μας παρουσιάζει τον ADF Controller και κατά επέκταση τα ADF task flows. Υπάρχει επίσης μια σύντομη αναφορά στα ADF regions και στο lifecycle. Προχωρώντας στο κεφάλαιο οκτώ ("Layout with Look and Feel") έχουμε μια ανάλυση του τρόπου παραμετροποίησης της εμφάνισης των σελίδων με την χρήση ADF skins. Επίσης, αμέσως μετά στο "Implementing Security" θα βρούμε απλά παραδείγματα ενσωμάτωσης security σε ADF εφαρμογές. Το προτελευταίο κεφάλαιο ("Deploying the ADF application") είναι πολύ χρήσιμο γιατί περιγράφει τη δομή των ADF distributables, την αξιοποίηση των ADF libraries, του MDS καθώς και της ρύθμισης του embedded Weblogic Server. To τελευταίο κεφάλαιο ("Advanced features of ADF") αναλύει μερικά από τα πιο προχωρημένα θέματα όπως optimizations για ADF BC, contextual events, MDS customization, JDeveloper extensions κ.α που σπάνια βρίσκονται συγκεντρωμένα σε ένα βιβλίο.

Η γενική γνώμη μου είναι πως το Oracle ADF 11gR2 Development Beginner's Guide είναι ένα χρήσιμο βιβλίο, προκειμένου κάποιος να μάθει γρήγορα και με απλό τρόπο τα βασικά του ADF. Τα αναλυτικά παραδείγματα του καθενός κεφαλαίου συνοδεύονται με το online code appendix που επίσης βοηθάει στο να δοκιμάσει κάποιος τις λύσεις στον JDeveloper. Από την άλλη μεριά, κάποιες προσθέσεις θα το έκαναν ακόμα καλύτερο. Για παράδειγμα τα βασικά που ζητάει οποιοσδήποτε που ξεκινά με το ADF όπως δημιουργία search forms και κριτηρίων, συνδυαστικά (join) view objects, βασικός προγραμματισμός σε JSF και πρόσβαση στα bindings κλπ ή οι αναλογίες με άλλα Java/.NET ή Oracle Forms frameworks..

Apr 15, 2013

Αλλάζοντας τα περιεχόμενα ενός .ear αρχείου μέσω ANT scripting

Δεν είναι σπάνιες οι περιπτώσεις που έπειτα από μια διαδικασία packaging θα χρειαστεί να αλλάξουμε κάτι στο παραγόμενο .ear αρχείο εφαρμογών μας. Για τους JEE και τους custom descriptors, ο Weblogic υποστηρίζει τα deployment plans (http://docs.oracle.com/cd/E11035_01/wls100/deployment/config.html) Ίσως πάλι να χρειαστεί να αλλάξουμε κάτι περισσότερο "εσωτερικό", πχ κάποιες κλάσεις ή properties αρχεία. Σε μια ανάλογη περίπτωση, χρειάστηκε να χειριστώ ένα .ear αρχείο που προέκυψε από το ojdeploy του JDeveloper. Ένας σύντομος δρόμος επεξεργασίας, προσφέρεται από την ΑΝΤ βιβλιοθήκη GroboUtils (http://groboutils.sourceforge.net/index.html) που προσφέρει υπηρεσίες όπως alterEar, alterWar, κ.ο.κ.

Κατεβάζοντας τους κώδικες του GroboUtils, μεταφέρουμε το αρχείο GroboCodeCoverage-1.1.0-ant.jar στο $ANT_HOME/lib φάκελο μας. Έπειτα, θέλοντας ενδεικτικά να τροποποιήσουμε ένα properties αρχείο στη διαδρομή WEB-INF/classes (που βρίσκεται στο συμπεριλαμβανόμενο .war αρχείο) μπορούμε να έχουμε τους ακόλουθους κώδικες στο ANT script μας:

<taskdef resource="ant-grobocoverage.properties">
  <classpath>
    <pathelement location="/usr/share/java/lib/GroboCodeCoverage-1.1.0-ant.jar"/>
  </classpath>
</taskdef>
    <grobo-rezip>
    <alterEar src="${dist.dir}/ear/myapplication.ear">
        <alterWar src="myapplication_webapp1.war">
            <classes dir="${build.tmp.dir}" includes="**/Application.properties" />
        </alterWar>
    </alterEar>
</grobo-rezip>

Dec 16, 2012

Αναλυτική κριτική για το βιβλίο "Oracle ADF real world developer's guide"

Μετά από ένα μήνα περίπου blog-σιωπής λόγω άφθονων υποχρεώσεων, ας επανέλθουμε με την επισκόπηση ενός βιβλίου που είχαμε προαναγγείλει εδώ και καιρό. Πρόκειται για το "Oracle ADF real world developer's guide" του Jobinesh Purushothaman. Πρόκειται για τον νεώτερο τίτλο στην ADF βιβλιογραφία που καλύπτει την έκδοση 11g R2, και είναι γραμμένο από έναν άνθρωπο που γνωρίζει όσο λίγοι το framework. Ο Jobinesh  διαθέτει ένα εξαιρετικά επιτυχημένο blog που είναι μάλλον αδύνατον κάποιος να ασχολείται με το ADF και να μην έχει ανατρέξει κάποια στιγμή στο blog του. Ένας επιπλέον λόγος αναφοράς αυτού του τίτλου είναι πως  ένας από τους reviewers είναι ένας εξαιρετικός συνάδελφος και συνεργάτης, ο Δημήτρης Στασινόπουλος που εξίσου διατηρεί ένα δημοφιλές blog.

Είναι ενδιαφέρον να αντιπαραβάλει κάποιος το συγκεκριμένο βιβλίο με το επίσημο developer's guide της Oracle που εξάλλου μετράει γύρω στις 1820 σελίδες. Σε πρώτη φάση, η δομή των κεφαλαίων του βιβλίου ακολουθεί αυτή της επίσημης τεκμηρίωσης. Υπερτερεί όμως σε παραδείγματα και άφθονο πηγαίο κώδικα. Καλύπτει με λεπτομέρειες πολλά από τα ενδότερα στοιχεία του framework που δεν έχουν αναφερθεί αλλού όπως για παράδειγμα το πώς δουλεύει το locking, η διαχείριση transactions, το ADF lifecycle, χρησιμοποιούμενα αρχεία metadata και άλλα πολλά. Ιδιαίτερη έμφαση έχει δοθεί επίσης στα ADF Java APIs. O Jobinesh όταν αναφέρεται σε ένα θέμα πολύ συχνά περιγράφει σε πολύ αναλυτικό βαθμό και με παραδείγματα τα διαθέσιμα APIs και την ακολουθία εκτέλεσης τους στο runtime δίχως να αφήσει τίποτα ασχολίαστο. Από την άλλη, για θέματα που που είναι ήδη αρκετά καταγεγραμμένα στην επίσημη τεκμηρίωση είτε σε online πηγές δίνεται μια σύντομη περιγραφή και άμεσες παραπομπές ώστε να αποφεύγονται επαναλήψεις. Τέλος, αξίζει να αναφερθεί πως στα  σχετικά code downloads περιλαμβάνονται όλα τα παραδείγματα του βιβλίου, κάτι που δεν συμβαίνει με όλους τους τίτλους της Packt, και είναι εξαιρετικά χρήσιμο.

Τα περιεχόμενα του βιβλίου περιλαμβάνουν δώδεκα κεφάλαια, τα μισά από τα οποία αναφέρονται στα ADF BC, τα υπόλοιπα τέσσερα στα ADF Faces και στον ADF Controller. Υπάρχουν και δυο μεικτά κεφάλαια σχετικά με validations και best practices. Η εμμονή στην τεχνική λεπτομέρεια κάνει το βιβλίο πολύ χρήσιμο για μεσαίου και ανώτερου επιπέδου προγραμματιστές του ADF, αλλά σε καμία περίπτωση δεν θα το συνιστούσα για πρώτο ανάγνωσμα σε 4GL (Forms) ή Java/JEE developers.

To πρώτο κεφάλαιο ("Getting started with Oracle ADF") περιγράφει στα γρήγορα έναν κύκλο ανάπτυξης σε ADF καθώς και συνοδευτικά εργαλεία δίνοντας αναλογίες με ένα σύγχρονο JEE τρόπο προγραμματισμού. Έπειτα ("Introduction to ADF Business Components") περιγράφονται με συντομία τα ADF BC καθώς και οι διαδικασίες ανάκτησης δεδομένων (queries) και οριστικοποίησης αλλαγών (commit) πάντα φυσικά με UML sequence διαγράμματα και πολλές λεπτομέρειες. Συνεχίζουμε με την περιγραφή των entity objects (κεφάλαιο 3) και των view objects (κεφάλαιο 4) καλύπτοντας εξαιρετικά όλες από τις δυνατότητές τους τόσο σε δηλωτικό (declarative) όσο και σε προγραμματιστικό επίπεδο. Η διαχείριση του κύκλου ζωής entities και view objects είναι αντικείμενο του "Advanced Concepts on Entities Objects and View Objects" όπου γίνεται μια θαυμάσια παρουσίαση και των σχετικών APIs τόσο για transactions όσο και για queries. Εξίσου ενδιαφέρον είναι και το κεφάλαιο για τα Application Modules, καλύπτοντας διάφορες πτυχές παραμετροποίησης (tuning parameters, shared modules, passivation, savepoints, κ.α.)

Στο κεφάλαιο "Binding Business Services with the User Interface" μαθαίνουμε πολλά για τους διάφορους τύπους ADF bindings, τα metadata αρχεία τους και τη διασύνδεση με Servlets. Μετά ("Building Data Bound Web User Interfaces") περιγράφονται ανάμεσα στα άλλα συνοπτικά τα components των ADF Faces και το δέσιμο τους με το ADF model, οι iterators και η σύνθετη διαμόρφωση των ADF query panels. Τα κεφάλαια 9 και 10 αναφέρονται στα ADF task flows, στο transaction management τους, στα regions, στα trains καθώς και μια ενδιαφέρουσα αναφορά στα savepoints. Στο "More on Validations and Error Handling" βλέπουμε λεπτομέρειες στον χειρισμό τους στο επίπεδο των ADF Faces και του ADF Model σε σχέση με τον κύκλο ζωής τους. Το κεφάλαιο 12 ("Oracle ADF Best Practices") συμπυκνώνει αρκετές πρακτικές οργάνωσης και επιλογές παραμετροποίησης για την καλύτερη απόδοση και επεκτασιμότητα των ADF εφαρμογών και έτσι κλείνει ιδανικά το βιβλίο.

Για όσους λοιπόν θέλουν να επεκτείνουν τις γνώσεις τους στο ADF, να καταλάβουν την εσωτερική λειτουργία των δυνατοτήτων του καθώς και να μάθουν πολλές δυνατότητες παραμετροποίησης (και αντίστοιχα APIs) τότε αυτό το βιβλίο είναι σταθμός. Ο Jobinesh περιγράφει αναλυτικά κάθε γνώρισμα σε μεγάλο βάθος δίνοντας πολλαπλές προοπτικές, προβλέποντας πιθανές ερωτήσεις του αναγνώστη. Πιστεύω μάλιστα πως το βιβλίο θα ήταν ακόμα πιο ισχυρό αν περιελάμβανε περισσότερες λεπτομέρειες σχετικά με τα ADF Faces αλλά και εξίσου προηγμένες δυνατότητες όπως τη χρήση javascript, θέματα ασφάλειας, personalization, κ.α. που μερικές φορές θα καταφύγει κάποιος σε ένα έργο με βάση αυτή την τεχνολογία.

Nov 1, 2012

Νέο βιβλίο για το ADF! Oracle ADF real world developer's guide

Ένας νέος τίτλος προστέθηκε στα (ήδη αρκετά) βιβλία για το Oracle ADF. Πρόκειται για το "Oracle ADF real world world developer's guide" του πολύ γνωστού ADF blogger και consultant Jobinesh Purushothama. Όπως φανερώνει ο τίτλος, του πρόκειται για έναν πρακτικό και αναλυτικό οδηγό (540 σελίδες περίπου) για προγραμματιστές ADF που περιγράφει με μεγάλη λεπτομέρεια και πολλές "εσωτερικές" πτυχές του framework. Στις επόμενες ημέρες θα δημοσιεύσω μια κριτική για το βιβλίο, καθώς είναι ενδιαφέρον να δούμε το πώς συγκρίνεται σε σχέση με άλλους ADF τίτλους καθώς και με το επίσημο developer's guide της Oracle.

Προς το παρόν, περισσότερες πληροφορίες θα βρείτε εδώ, ενώ ένα ενδεικτικό κεφάλαιο μπορείτε να το κατεβάσετε εδώ.

Jul 3, 2012

Μερικές πληροφορίες για declarative XML generation από το ADF


Τα ADF View Objects που κατασκευάζουμε μπορούν εύκολα να εξαχθούν σε μορφή XML. To API του oracle.jbo.server.RowImpl (που κληρονομείται από Entities και View Objects) μας δίνει διάφορες εκδοχές της μεθόδου writeXML() ώστε να ορίσουμε το βάθος της εξαγωγής, την ενδεχόμενη χρήση XSLT, τα πεδία που θα παραχθούν κλπ. Υπάρχουν ταυτόχρονα και μερικά "κόλπα" που μπορούμε να χρησιμοποιήσουμε από τους declarative editors, όπως:

  1. Τον προσδιορισμό του ονόματος (element name) που θα έχει κάποιο συγκεκριμένο πεδίο. Ανατρέχουμε λοιπόν στα Custom Properties του πεδίου και ορίζουμε την ιδιότητα XML_ELEMENT στο επιδιωκόμενο XML element name. Διαφορετικά, θα χρησιμοποιηθεί το attribute name, όπως έχει αποδοθεί από το ADF.


2. Σε περίπτωση που ένα πεδίο είναι κενό (null) τότε δεν θα εμφανιστεί στο παραγόμενο XML, εκτός και αν οριστεί με οποιαδήποτε τιμή (πχ 1) το custom property XML_EXPLICIT_NULL.
3. Για την ονομασία των root elements, χρειαζόμαστε δυο προσδιορισμούς: ο ένας για το result set (στην ουσία το view object/entity name) και ο δεύτερος σε επίπεδο εγγραφής. Στο ADF Entity/View Object μας προσθέτουμε τα custom non-translatable properties XML_ELEMENT, XML_ROW_ELEMENT.

 Περισσότερες πληροφορίες από το Oracle Documentation εδώ.

Apr 12, 2012

Νέο βιβλίο για το ADF 11g - Oracle JDeveloper 11gR2 Cookbook

Το τελευταίο βιβλίο που προστέθηκε στη λίστα αυτών που ασχολούνται με το ADF είναι το Oracle JDeveloper 11g R2 Cookbook της Packt Publishing. Με μεγάλη μου χαρά θα προσπαθήσω να μεταφέρω τις εντυπώσεις μου, καθώς συγγραφέας του είναι ο Νίκος Χαραλαμπίδης (που συντηρεί τα δημοφιλή blogs JDeveloper FAQ και ADF Code Bits) με τον οποίο συνεργάστηκα στο επιτυχημένο και σύνθετο έργο της μετάπτωσης των Oracle Forms 6i σε ADF 11g της Mednet International.

Παρακολουθώντας το ADF εδώ και περίπου μια δεκαετία, είναι πράγματι εντυπωσιακό πως σήμερα υπάρχουν αναρίθμητες πηγές πληροφορίες, είτε πρόκειται για επίσημη τεκμηρίωση, τίτλους βιβλίων ή άρθρα bloggers. Είχαμε αναφερθεί στο παρελθόν σε κάποιους τίτλους όπως για παράδειγμα το Oracle ADF Enterprise Application Development made simple ενώ υπάρχουν και αρκετοί από το Oracle Press. Η θεμελιώδης διαφοροποίηση του JDeveloper Cookbook (που μάλλον ορθότερα θα έπρεπε να είχε ονομαστεί ADF Cookbook) είναι ότι προϋποθέτει μια εις βάθος γνώση του ADF και δεν καταπιάνεται με την ερμηνεία ή την περιγραφή των βασικών εννοιών: αντίθετα προτείνει λύσεις σε συντεταγμένα προβλήματα της ανάπτυξης λογισμικού, που προκύπτουν αναμφίβολα όταν μια καλά δομημένη ομάδα αναλαμβάνει να εκτελέσει ένα μεγάλο έργο και χρειάζεται έναν ενιαίο τρόπο αντιμετώπισης διαφόρων ζητημάτων.

Έχουμε να κάνουμε λοιπόν με πάνω από 120 "συνταγές" σε θέματα ανάπτυξης στο ADF 11g, διατρέχοντας το ADF BC, τον ADF Controller, το επίπεδο του JSF και διάφορα κάθετα θέματα όπως debugging, deployment, tuning, κλπ. Το στυλ της παρουσίασης των θεμάτων είναι εξαιρετικό και ακολουθεί αυτό των blogs του Νίκου: περιγράφεται αρχικά το πρόβλημα, δίνεται μια αναλυτική, βήμα-βήμα προσέγγιση επίλυσης με συνοδευτικά screenshots, ακολουθεί μια εις βάθος ερμηνεία για τον τρόπο λειτουργίας της λύσης και στο τέλος υπάρχουν σχόλια για επεκτάσεις ή αναφορές. Στα πλεονεκτήματα αυτού του βιβλίου θα πρέπει επομένως να συνυπολογίσουμε το στυλ της γραφής που είναι άμεσο, κατανοητό και πλήρες. Στη διάρκεια της περιγραφής των "συνταγών" παραδίδεται άφθονος κώδικας που επίσης περιλαμβάνεται ανά κεφάλαιο στο online παράρτημα του βιβλίου, κάτι που επίσης μου άρεσε πολύ. Οι περισσότερες συνταγές αφορούν συχνά προβλήματα στην ανάπτυξη ADF εφαρμογών, γεγονός που τις κάνει πολύ χρήσιμες. Από την άλλη, υπάρχει κατά περίπτωση μια ανισορροπία στην επιλογή των συνταγών: κάποιες προσφέρονται εδώ και καιρό από την επίσημη τεκμηρίωση της Oracle (δηλαδή το Fusion Middleware Developer's Guide), άλλες είναι εξαιρετικά απλές, άλλες κάπως πιο σύνθετες, ενώ απουσιάζουν κάποια σημαντικά θέματα κατά τη γνώμη μου, σχετικά με transaction management, javascript support, ADF regions, κ.α. Ας δούμε όμως με περισσότερες λεπτομέρειες τα κεφάλαια αυτού του βιβλίου:

Το πρώτο κεφάλαιο (Prerequisites to Success: ADF Project Setup and Foundations) έχει να κάνει με τη ρύθμιση του JDeveloper σε περιβάλλον Linux, τη δημιουργία των βασικών κλάσεων ενός έργου, τον τεμαχισμό σε βιβλιοθήκες, το logging, τη δημιουργία page templates ή τη δημιουργία ενός custom generic actions framework. Τόσο το κεφάλαιο των βιβλιοθηκών, όσο και των page templates ή των βασικών κλάσεων καλύπτονται αρκετά αναλυτικά από την τεκμηρίωση της Oracle και ίσως μια απλή αναφορά θα ήταν αρκετή. Στο δεύτερο κεφάλαιο (Dealing with Basics: Entity Objects) δίνονται συνταγές για την κατασκευή κλειδιών από Oracle Sequences, για τη διαχείριση του κύκλου ζωής ενός entity (doDML, removal, child removal, validation) και αν και υπάρχουν επικαλύψεις στην τεκμηρίωση είναι ένα πολύ καλό κεφάλαιο. To ίδιο ισχύει και με το "A Different Point of View: View Object Techniques" που περιγράφει το iteration στις εγγραφές ενός view object, την αλλαγή των ιδιοτήτων updateable και queriable προγραμματιστικά ενός πεδίου, τον ορισμό του currentRow πριν και μετά από ένα rollback, την ανίχνευση νέων εγγραφών, την αλλαγή του WHERE clause, κλπ. Ίσως θα ήταν προτιμότερο να συγχωνευτεί εννοιολογικά με το επόμενο κεφάλαιο ("Important
Contributors: List of Values, Bind Variables, View Criteria") που επίσης καλύπτει κάποια ήδη γνωστά θέματα (cascade lovs, lov switcher, view criteria) αλλά προστίθενται και άλλα όπως η αλλαγή ή ο καθαρισμός των bind variables ή η case-insensitive αναζήτηση.

Προχωρώντας στο κεφάλαιο 5 ("Putting them all together: Application Modules") θα βρούμε συνταγές για το πώς θα φτιάξουμε ένα Web Service από τα ADF BC μας και πώς αντίστοιχα θα το καταναλώσουμε ως Web Service client, ένα καλό παράδειγμα για την τροποποίηση της συμπεριφοράς activate/passivate του framework, τη δυνατότητα άντλησης στατιστικών για το Application Modules, shared LOV modules και επέκταση του Database Transaction Factory. Αμέσως μετά θα δούμε τεχνικές για τα task flows όπως την αρχικοποίηση τους (με custom μεθόδους από το Application Module ή με initializer), την κλήση ενός task flow URL, τη δημιουργία ενός train flow ή την ανάκτηση πληροφοριών μέσα από το MDS. To κεφάλαιο για τα ADF Faces εισάγει λίγα καινούργια στοιχεία αφού θέματα για την παραμετροποίηση του af:query, το χρήση του af:tree, του af:poll, του af:carousel, του af:selectManyShuttle ή του pop-up για την επεξεργασία εγγραφής περιγράφονται αναλυτικά στην επίσημη τεκμηρίωση. Ξεχωρίζει όμως εδώ η συνταγή για την χρήση page templates στα popups ενώ καλή είναι η ενδεικτική λύση για το export file αλλά ατυχής η υλοποίηση (όπου τα περιεχόμενα του αρχείου περιλαμβάνονται σε μια java.lang.String μεταβλητή)


Στο Backing not Baking:Bean Recipes έχουμε χρήσιμες συνταγές για ένα af:popup που θα ειδοποιεί για εκκρεμείς αλλαγές (pending changes), για custom selection listener, μια εξαιρετική αναφορά για custom query listeners και για popup που ενημερώνουν για μεγάλης διάρκειας συναλλαγές (transactions), την χρήση του af:iterator σε σχέση με ένα custom collection και μια αχρείαστη αναφορά στην εκμετάλλευση session μεταβλητών (που ούτως ή άλλως αποθαρρύνεται από το framework) To κεφάλαιο 9 (Handling Security, Session Timeouts, Exceptions, and Errors) δεν προσθέτει κάτι καινούργιο ως προς την διάσταση της ασφάλειας (για παράδειγμα αναφέρει τη λειτουργία του ADF Security Wizard, την προγραμματιστική πρόσβαση στο security context, μια custom login page) Αντίθετα, πιο ενδιαφέρουσες συνταγές είναι αυτές που περιγράφουν την διαχείριση του session timeout και την διαχείριση λαθών από έναν custom exception handler που μετασχηματίζει μηνύματα λαθών από τα ADF BC.


To κεφάλαιο του deployment (Deploying ADF Applications) περιγράφει ανάμεσα στα άλλα την χρήση του εργαλείου ojdeploy για την αυτοματοποίηση εργασιών (build και deploy) μέσω του Hudson. To επόμενο κεφάλαιο (Refactoring, Debugging, Profiling, and Testing) θα έλεγα πως περιγράφει περισσότερο θεωρητικά τις δυνατότητες της πλατφόρμας παρά δίνει πρακτικές συνταγές για την αξιοποίησή της. Θέματα που καλύπτονται εδώ είναι το database synchronization των ADF BC, το refactoring στα ADF BC, η δυνατότητα του remote debugging και του CPU profiling (που παρεμπιπτόντως δεν υποστηρίζεται στο Linux) η διαχείριση log μηνυμάτων και η χρήση του JUnit για unit testing. Σε έναν βαθμό, υπάρχει αποζημίωση στο τελευταίο κεφάλαιο (Optimizing,
Fine-tuning, and Monitoring) όπου δίνονται μερικές καλές συμβουλές για τη βελτιστοποίηση του ADF BC (απουσιάζουν όμως αντίστοιχες τεχνικές για τα ADF Faces), υπάρχει μια εξαιρετική συνταγή για τους Weblogic Work Managers και τέλος υπάρχει μια φτωχή αναφορά από την σκοπιά του ADF στο JRockit Mission Control για την παρακολούθηση ενός συστήματος.

Ως συμπέρασμα θα έλεγα πως το βιβλίο αυτό είναι ένα εξαιρετικό υπόδειγμα γραφής ώστε ομάδες ανάπτυξης να γράψουν τα δικά τους συνταγολόγια (cookbooks) προσαρμοσμένα στις ιδιαιτερότητες των έργων που έχουν να αντιμετωπίσουν, δανειζόμενες αρκετές από τις συνταγές του βιβλίου. Είναι επίσης ένα χρήσιμο βοήθημα γιατί συγκεντρώνει καλές πρακτικές σε έναν μόνο τίτλο. Από την άλλη, περιλαμβάνει και μερικά θέματα που έτσι και αλλιώς είναι καταγεγραμμένα σε μεγάλο βαθμό στην επίσημη τεκμηρίωση της Oracle, ενώ θα ήθελα να δω πολύ και συνταγές με άλλα εξελιγμένα ζητήματα όπως ADF regions, bindings, JSF 2.0, javascript integration, ui design και transaction management που απασχολούν ολοένα και περισσότερο πιο εξελιγμένα έργα βασισμένα στο ADF.

Ένα ενδεικτικό κεφάλαιο του βιβλίου βρίσκεται εδώ.

Nov 11, 2011

Locale switching στο JHeadstart και στο ADF

Μια συνηθισμένη απαίτηση έχει να κάνει με τη δυνατότητα επιλογής γλωσσικού περιβάλλοντος (locale) σε μια ADF εφαρμογή. Μια τέτοια ενέργεια θα έχει ως αποτέλεσμα την κατάλληλη διαμόρφωση των λεκτικών στοιχείων (labels), ημερομηνιών, αριθμών και ενδεχομένως και δεδομένων (πχ λίστες τιμών) στο περιβάλλον επιλογής του χρήστη. Μου αρέσει πολύ η υποστήριξη αυτής της δυνατότητας από το JHeadstart δίχως να χρειαστεί να γράψουμε γραμμή κώδικα και πρόκειται να την παρουσιάσω καθώς είναι εξαιρετικά χρήσιμη και σε καθαρά ADF projects, αν απλά ανατρέξουμε στον πηγαίο κώδικα της υλοποίησης.

Πρώτα από όλα, την δυνατότητα επιλογής γλώσσας θα τη δίνουμε στους χρήστες μας κατά τη διάρκεια του login. Διαφορετικά μπλέκουμε σε καταστάσεις cancel edit και requery objects αν αυτοί βρίσκονται ήδη σε μια σελίδα με αλλαγές ή που παρουσιάζονται δεδομένα από φιλτραρισμένες λίστες με βάση το locale. Στη login.jspx, αντιγράφουμε κάτω από το πεδία username και password τον παρακάτω κώδικα από το templates/default/misc/file/menuGlobal.vm ώστε να προκύψει και ένα choice list για την επιλογή της γλώσσας. Διορθώνουμε μόνο την ιδιότητα labelAndAccessKey ώστε να ανταποκρίνεται στο λεκτικό της επιλογής μας:

<af:selectOneChoice id="localeSwitcher" immediate="true" autoSubmit="true"
labelAndAccessKey="${JHS.nls('Language','LANGUAGE_SELECTOR_LABEL')}"
valueChangeListener="#{jhsLocaleManager.changeLocale}"
value="#{jhsLocaleManager.currentLocale}">
<af:forEach items="#{jhsLocaleManager.supportedLocales}" var="row">
<af:selectItem value="#{row.locale}" label="#{row.description}"/>
</af:forEach>
</af:selectOneChoice>

Τώρα, ας ορίσουμε τις υποστηριζόμενες γλώσσες. Στο definition file του JHeadstart υπάρχουν οι ανάλογες ρυθμίσεις για το default locale, τα υπόλοιπα υποστηριζόμενα καθώς και τον τρόπο επιλογής του αρχικού.

Παράγοντας τις σελίδες, θα εμφανιστεί στο login και ο επιλογέας γλώσσας με εξ ορισμού τιμή αυτήν του browser μας. Ανάλογα με την επιλογή της γλώσσας, από εδώ και στο εξής στην πλοήγηση μας στην εφαρμογή θα εμφανίζονται τα αντίστοιχα μεταφρασμένα μηνύματα.

Αν θέλουμε επιπλέον να μεταφράσουμε και δεδομένα όπως λίστες τιμών που φιλτράρονται σύμφωνα με τη γλώσσα επιλογής, τότε θα χρειαστεί να δούμε λίγο τα ενδότερα του JHeadstart. Πιο συγκεκριμένα, στοιχεία του συνδεδεμένου χρήστη αποθηκεύονται σε μια session μεταβλητή ονόματι jhsUser (και τύπου: oracle.jheadstart.model.JhsUser) που περιλαμβάνει το πεδίο locale που παίρνει τιμές κατά το login μας (στο παράδειγμα μας 'en' ή 'el') Άρα μπορούμε να το χρησιμοποιήσουμε ως bind variable για φιλτράρισμα με expression της μορφής: adf.userSession.userData.jhsUser.locale.

Oct 6, 2011

Καθαρίζοντας (clean) σκουπίδια στο jazn-data.xml

Κατά τη διάρκεια της ανάπτυξης μιας ADF εφαρμογής, οι προγραμματιστές φτιάχνουν και αφαιρούν task flows. Ίχνη αυτής της εξέλιξης βρίσκονται στο jazn-data.xml εφόσον τα task flows συνδέονται με security (γεγονός που ισχύει σχεδόν πάντα) Ωστόσο, ο JDeveloper και ειδικά ο security configuration editor για το ADF, ποτέ δεν πρόκειται να μας επισημάνει πως κάποιες εγγραφές στο jazn-data.xml δεν ισχύουν, αφού πια δεν υπάρχουν τα pages, task flows ή regions στα οποία αναφέρονται. Σε ένα έργο που απουσιάζει αυτός ο έλεγχος, δεν θα αργήσει να καταλήξουμε σε ένα τεράστιο jazn-data.xml αρχείο με πολλά στοιχεία του ανενεργά ή λανθασμένα.

Δεν υπάρχει ένας τυποποιημένος και απλός τρόπος να κάνουμε το housekeeping του jazn-data.xml. H μέθοδος που ακολουθώ, στηρίζεται στα εξής βήματα:

1. Από το υπάρχον jazn-data.xml βρίσκουμε όλες τις αναφορές που αναφέρονται σε task flows. Μπορούμε να χρησιμοποιήσουμε το XPath Search για να ανακτήσουμε όλη τη λίστα των task flows, pages ή regions που είναι αντικείμενα security permissions. Η έκφραση που αναζητώ είναι η "//permission/name/text()". Τον πίνακα των αποτελεσμάτων τον κάνω copy-paste σε ένα αρχείο.



2. Ως προς τη λίστα των ενεργών task flows, με βοήθησαν τα custom build scripts (προσοχή: καμία σχέση με JDeveloper ή ojdeploy) που συγκεντρώνουν σε έναν κατάλογο όλα τα task flows. Με Linux scripting μπορώ να πάρω όλα τα ονόματα των αρχείων, ή καλύτερα των task flows files αν προτιμάτε και να την αποθηκεύσω σε ένα δεύτερο αρχείο.

3. Συγκρίνοντας τα δυο αρχεία, εντοπίζουμε τις διαφορές και τελικά διορθώνουμε το αρχικό μας jazn-data.xml ώστε να περιλαμβάνει μόνο έγκυρες και ισχύουσες εγγραφές.

Sep 9, 2011

Πώς να συγχρονίσουμε τις αλλαγές που έχουν συμβεί σε ένα Application Module προτού καλέσουμε μια PL/SQL procedure

Το παράδειγμα είναι συγκεκριμένο: έχουν συμβεί διάφορες αλλαγές σε ένα ApplicationModule (ή/και σε nested application modules αυτού) και προτού καλέσουμε μια PL/SQL procedure που θα επεξεργαστεί τα δεδομένα που έχουν αλλαχτεί, θέλουμε να διασφαλίσουμε πως αυτά είναι διαθέσιμα στο επίπεδο της βάσης. O συγχρονισμός αυτός επιτυγχάνεται σε επίπεδο application module με την κλήση:

am.postChanges();