Sunday, September 25, 2011

How To Speed Up Application Undeployment in JDeveloper 11g R2

There was new patch set released this week for JDeveloper 11g R2, its called (11.1.2.1.0). I had a quick look, there are still few issues left from previos release (11.1.2.0.0), but overall this new update looks better and more stable.

Update: Same applies for JDeveloper 11g R1.

This post describes issue related to long application undeployment time. Reproduced when running on embedded WLS directly from JDev. I had this issue in (11.1.2.0.0), same reproduced with (11.1.2.1.0).

Sample app is fairly basic, it contains one ADF BC AM, read-only VO and one JSF page - ADFAppADFBCSimple11R21.zip:


As per documentation chapter 9.3 Configuring Your Application Module Database Connection, 11g R2 differently than 11g R1, automatically assigns JDBC Data Source name for newly created AM - java:comp/env/jdbc/HrDSDS:


This is good, but once we need to restart application, or even stop it from JDev:


It takes in average 2 minutes to undeploy ADF app. It says - resource pool shutting down, ignoring 1 resource still in use by applications:


If we switch to JDBC URL type and provide connection name, as it was by default in 11gR1:


As we can see from the log, when connection is changed to be JDBC URL type, application is undeployed just in 2 seconds:


2 minutes vs. 2 seconds, I guess difference is obvious? :)

Let's dig deeper.

We can remove data source prefix and leave only - jdbc/HrDSDS:


This would need to define data source on WebLogic manually, when we have prefix java:comp/env/ it means JDev will create temporary data source automatically. I have defined jdbc/HrDSDS manually:


Application is undeployed fast as well, same as using JDBC URL - around 2 seconds:


Lesson learned - in 11g R2, until it will be fixed - don't use auto generated prefix name java:comp/env for data sources. Always define data sources manually on WebLogic or use JDBC URL, as it was default in 11g R1.

Wednesday, September 21, 2011

How to Disable WebLogic Administrator from WebCenter 11g PS3/PS4 Portal Applications Management

While testing your WebCenter 11g PS3/PS4 application security, don't forget to check how portal application behaves for WebLogic administrator user. Typically we don't want to grant admin access to portal for the same user who is administering WebLogic server. Let's see how it works.

Download sample application, where admin access is disabled for WebLogic administrator - EnterprisePortalApp_v9.zip.

When we generate new WebCenter 11g PS3/PS4 application, JDeveloper constructs default UI template. This template is applied for portal pages. Because application is deployed on WebLogic server, and weblogic admin user is one of the users available in security provider - obviously we can login into our application as weblogic user and authentication will be completed successfully:


What about authorization? It seems like by default WebLogic administrator is granted portal admin access as well - Administration link is visible:


It depends on requirements, but in most of the cases we don't want to grant portal admin access to WebLogic administrator. How to disable it?

First place to look - generated UI template. As we can see, showAdmin template attribute by default is enabled to all authenticated users. There is no much logic here, why all authenticated users should see portal Administration link:


We can fix it, by changing showAdmin value to check against Administrator role from ADF Security. Only portal administrators will be able to see Administration link:


We test again, still get same result - WebLogic administrator is able to access Administration link:


Seems like ADF Security role - Administrator is mapped with admin group from WebLogic. We can double check ADF Security configuration - Administrator role is mapped with our custom PortalManager group:


In turn, PortalManager group is assigned for redsam and scott users only, there is no WebLogic admin here:


Ah, here is a trick. Its not visible through wizard and is hidden, you should open Source Code view for ADF Security definition. Only in Source Code view we can see, that ADF Security role "Administrator" is mapped with WebLogic admin group called - "Administrators". We can remove this mapping:


WebLogic administrator will not be able anymore to perform portal application administration - link for Administration resources becomes disabled as well:


Try to login with real portal administrator - redsam user:


Redsam user is granted with ADF Security role - Administrator, access to administration resources is granted:


Friday, September 16, 2011

Integrating UCM Wiki Content Presenter into WebCenter 11g PS3/PS4

WebCenter 11g PS3/PS4 is able to store and retrieve Wiki content directly to and from Oracle UCM Content Server. Thats really good improvement comparing with early WebCenter releases, because there is no need to run separate server just to maintain static Wiki content. However, there are few tips and tricks to know, when integrating and making it work together with WebCenter Portal Framework application. This post will explain how to publish static Wiki content inside WebCenter Portal Framework application with the help of WebCenter Content Presenter ADF Task Flow.

Sample application defines connection to UCM server, you should change these details according to your infrastructure:


Download sample application for this post - EnterprisePortalApp_v8.zip.

Menu is implemented using WebCenter Portal Framework menu model. Wiki content will be retrieved and displayed in the menu using Content Query - Static Content:


In WebCenter PS3/PS4, we can construct menu from list of documents dynamically, based on UCM query. Content Query retrieves Wiki documents of type text/html, by specified Tag - populated list will be converted into menu automatically (make sure Insert Folder Contents option is set):


You may wonder, what is this Tag, which we are using to construct menu list. Tag is defined directly inside UCM, for example if we have documents stored in UCM:


Each of the documents/folders can be assigned with specific Tag, we can use this tag from WebCenter menu model Content Query:


Here is example of menu list populated from Content Query, Wiki document is loaded based on menu selection. All such menu links, generated based on Content Query, are rendering Wiki content directly inside Content Presenter:


We can edit Wiki document, because content is loaded inside Content Presenter automatically. Let's specify a link to another Wiki document available in UCM:


Wiki document is updated inside Content Presenter, using Rich Text editor:


Let's see what will happen, when we click on newly added link to another Wiki document:


When link to another Wiki document is clicked, WebCenter is loading Document Viewer task flow and opens referenced Wiki document:


Its not what we want, there is no need to open Document Viewer, we want to open Wiki document as static HTML page. Even more, when Document Viewer is opened from Wiki link, it destroys WebCenter menu model - portal application becomes broken (even Logout doesn't work):


But don't worry ! There is option to force Wiki links to behave as simple links and load static content - 31.3.5 Displaying Wiki Page Links Within Content Presenter. We need to update adf-config.xml file with Wiki resource handler:


Let's try to click on Wiki link again:


It works now ! Referenced Wiki document was loaded, even menu selection was updated automatically - thats what we need:


Thursday, September 15, 2011

Programmatic ADF Task Flow Router

Blog reader is asking how to control ADF Task Flow navigation programmatically (JDeveloper 11g and ADF Task Flow Parameters), in order to minimize predefined static outcomes inside ADF Task Flow diagram. I would go with simplest option and use Router activity available for ADF Task Flows. However, depending on use case, we may require to implement routing logic inside custom Java method.

Sample application - ADFConditionalNavigation.zip, explains how to implement programmatic ADF Task Flow router inside Java bean class. This sample is implemented using latest JDeveloper 11g R2, but same logic can be applied with previous JDeveloper 11g versions as well.

For the test case, I have defined three buttons, each assigned with af:setPropertyListener:


Each button points to the same navigation outcome called route:


This is the reason, why we are using af:setPropertyListener, to distinguish navigation outcome dynamically. Navigation outcome name for each of the buttons is stored inside our custom bean from View scope:


There is a bug in JDeveloper 11g R2 IDE, it can't resolve managed bean methods or properties declared in any scope except session or request (see 'To' part highlighted in red). Good thing this is only IDE bug, on runtime it works well. Our managed bean is declared in view scope, to make sure stored outcome name will be available for programmatic routing:


Navigation from main page is always performed only through route outcome. Next we are hitting Method Call - it calls our custom method from managed bean. This custom method evaluates current dynamic outcome name and returns real outcome (which will be jobs or empls in our case):


If we look into Method Call properties, we will see custom method name with routing logic (IDE bug makes it look red, same as explained above). Instead of using Fixed Outcome, toString() = true option is specified. This means instead of using predefined outcome name, ADF will use return value of our custom method as navigation outcome:


Let's look into custom router method code. Nothing complex - we are checking value of dynamic outcome initialized from af:setPropertyListener and based on defined condition returning first or second real outcomes. First two buttons are navigating to empls, third button navigates to jobs:


Thursday, September 8, 2011

Another Way to Invoke Managed Bean Method

Typically we are calling managed bean methods through expression language in Oracle ADF. Depending on use case, it may by useful to know how to call managed bean method directly by acquiring instance of that bean.

My example contains session scope bean:


This bean implements collection of elements and contains one method to retrieve collection element by code - getElementName(String):


This method accepts parameter and returns value, how we would invoke such method from another bean? There are several options, one of them is to acquire managed bean instance and call method directly - AccessingBeanInstance.zip sample application for this post.

As we can see in this example, with JSFUtils helper method bean instance is being retrieved. If its first access, bean will not be instantiated yet, so we need to create new instance. Once instance is created, we can call custom method and store same instance in session scope - so it will be reused for future requests:


Wednesday, September 7, 2011

ADF/WebCenter Spaces 11g/BPM Suite 11g Integration - Online Oracle University Training

Are you interested to know how to integrate it all together - ADF, WebCenter and BPM? For 11-12 October 2011 is scheduled online training, where I will be explaining all technical details for such integration. Registration is available through Oracle University:


Training agenda:

Day 1 (10:00 – 18:00 CET) 
Oracle ADF Development for BPM 11g

This session explains in detail how to develop using Oracle ADF for BPM 11gSuite and how to implement Human Task forms following ADF development best practices. Participants will be guided with sample applications through the following topics:

  • ADF BC usage with Custom UI for BPM Human Task Development 
  • BPM Human Task Data Control reusability 
  • Custom ADF Task Flow based on BPM Human Task implementation 
  • ADF Rich Faces UI development for BPM Human Task 
  • Dynamic ADF UI implementation for BPM Human Tasks, based on process payload 

Day 2 (10:00 – 18:00 CET) 
BPM 11g Integration with WebCenter Spaces 11g 

The second day is focused on deep diving into BPM 11g portal setup with WebCenter Spaces 11g. Participants will learn how to accomplish the following tasks through live demonstrations:

  • Extending WebCenter Spaces 11g with BPM 11g functionality 
  • Customizing BPM Process Spaces inside WebCenter Spaces 11g

Thursday, September 1, 2011

Making It Work Together - MDS User and Seeded Customizations

MDS is one of the most powerful and important elements of ADF/WebCenter framework. Users can perform ADF UI personalizations on runtime through MDS, as well as developers can implement seeded MDS customizations on design time and modify ADF components for different targets. However, if you would try to enable and run both options together - MDS User and Seeded Customizations, it will not work out of the box. My today post is about how to make it work together. Before reading this post, I would highly recommend to read previous posts:


Sample application (EnterprisePortalApp_v7.zip) is enabled with both - MDS User and Seeded Customizations:


MDS Seeded Customizations are functional on SiteCC level, because seeded customizations should be applied on application scope. This means MDS should be configured with SiteCC class:


All good at this point, let's login into portal application as user redsam:


MDS Seeded Customization works, we see our changes applied:


Let's apply user personalization now, hide few table columns - ManagedId, LocationId, for redsam user:


Login with different user, for example scott:


We faced an issue now - MDS personalizations from user redsam are visible for user scott:


This happens because MDS is configured with SiteCC class (for MDS Seeded customizations to work), so all personalizations are getting stored in application scope and are visible to every user. We can fix this by enabling our custom MDS session options factory class and programmatically merging custom UserCC and SiteCC layers (described in this blog - Applying Personalization and Customization in Oracle ADF 11g and Oracle WebCenter 11g). Predefined VIEW_LAYER will combine both SiteCC and UserCC inside custom Session Options Factory class and allow to operate both MDS Seeded Customizations and User Personalizations without conflict:


Custom Session Options Factory class must be registered inside adf-config.xml, page-editor-config tag:


In order for this Custom Session Options Factory to be enabled, we need to define WebCenter Composer filter inside web.xml:


Don't forget to define filter mapping for WebCenter Composer filter in web.xml:


Let's perform user personalization again, after applying all the changes mentioned above - reorder DepartmentName column by user redsam:


Login as another user scott, MDS Seeded Customizations are working well:


MDS User Personalization works now as well, personalizations from user redsam are not visible anymore for user scott:


MDS behaves correctly now, personalizations are stored under personal MDS folder:


Okej, so it all works now. However, there is one more trick you should keep in mind, when you would apply MDS Seeded Customization next time. Custom SiteCC layer is defined with webcenter value:


Before switching to Customization Developer mode and starting working with MDS Seeded Customization, make sure you switch temporary from SiteCC to UserCC customization class in adf-config.xml. This is needed, because we want to apply application scope customizations. Switch it back to UserCC, once seeded customization development is done:


In Customization Developer mode:


Make sure customization mode is set to webcenter:


This will store MDS Seeded Customizations under webcenter path:


Same webcenter name is defined for custom SiteCC layer:


Once back to normal mode, don't forget to switch back to UserCC - this will ensure proper user personalization functionality: