Pages

Showing posts with label 12c. Show all posts
Showing posts with label 12c. Show all posts

The Struggles of Personalization in ADF

A Mike Heeren & Richard Olrichs co-production

ADF comes with the out-of-the-box features of personalization. This means that whenever you configure personalisation, users can persist changes they make to the application across sessions and personalize their experience with the application. We have seen that this feature can also confuse some of our users, so it is not always wise to use this. It depends on the use case you have. However, when recently implementing personalization on an ADF 12.2.1.2 application, we had a couple of issues regarding persisting these personalizations to the MDS.

We felt that most of the blogs we came across while implementing these features, share the joyful out-of-the-box configuration. Just select some of the checkboxes in the properties and you are done, ready to enjoy your beer and have your designers and product owners cheer for you.
Sometimes however, real life applications at customers do not match the out-of-the-box configuration and things can become a little bit more tricky than you might expect.

Let's start at the top, and go through some of the steps you will always need within your application for personalization to work. You need to have authentication and authorization set up. If you also want to follow our struggles, we have posted a sample application at the end of this blog to show both the problems as well as the solutions.

Getting started with customizations

The basic configuration of customization in ADF is pretty simple. We start with a simple ADF application (with authentication already configured), and select the Project Properties > ADF View. Here we check Enable user customization and Across sessions using MDS, as seen below:



When enabling user customizations, the following files are edited:
In the adf-config.xml file the following lines are added:

 
  oracle.adf.view.rich.change.MDSDocumentChangeManager
 


In the web.xml file the javax.faces.FACELETS_RESOURCE_RESOLVER context-param is changed from oracle.adfinternal.view.faces.facelets.rich.AdfFaceletsResourceResolver to oracle.adfinternal.view.faces.facelets.rich.MDSFaceletsResourceResolver, and the following blocks are added:

 adflibResources
 oracle.adf.library.webapp.ResourceServlet

...

 adflibResources
 /adflib/*

...

 ADFLibraryFilter
 oracle.adf.library.webapp.LibraryFilter

...

 ADFLibraryFilter
 /*
 FORWARD
 REQUEST

...

 oracle.adf.jsp.provider.0
 oracle.mds.jsp.MDSJSPProviderHelper


 org.apache.myfaces.trinidad.CHANGE_PERSISTENCE
 oracle.adf.view.rich.change.FilteredPersistenceChangeManager


Finally, the following block will be added to the project .jpr file:

 
 


After this we need to configure the adf-config.xml file and add the oracle.adf.share.config.UserCC Customization Class on the MDS tab. This is a default customization class that is shipped with ADF. You can also write your own, but that is more of a use case for customization than it is for personalization. In our case we’ll just configure the application using the UserCC:



Now you need to configure the components that you want the end user to be able to personalize. This can be done in the View tab. Select the ADF Faces Components Tag Library, because we want to personalize the table and column components, these are default component from ADF Faces. By default all attributes will be persisted, you can uncheck them if you do not wish to persist these:



After the above steps are configured, you can give a fancy demo on your demo application, and everybody is happy. However, in our production application, there were still a few issues to tackle, we struggled with some of these.

Struggle 1: Task flows from libraries combined with a file based MDS on a Windows machine.


Our application was not a simple MVC application, but like many application out there, we used ADF libraries to include taskflows from library projects and included them in a bigger main application. When we turned on personalisation on components from task flows which come from libraries instead of directly from the application, they were not correctly persisted to the file based MDS on Windows machines.

When running the application via JDeveloper (in our example application by right clicking default.jsf in the ViewController project, and selecting Run), we see that the task flow that comes directly from the ViewController project (the table on the left of the screen), behaves as expected. However, when personalizing the table from the task flow that comes from the imported library (so from the ViewControllerLibrary project), we see the following warning in the log files.

    

We can verify that the preferences were persisted to the MDS for the left table, but not for the right table, by opening the application (with the same user) in another browser:



Unfortunately, this issue occurs when using task flows from libraries in combination with using a file based MDS on a Windows machine. Weblogic is not able to create a file path, which contains !/ (which is used to indicate that the resource is part of a library).

Luckily, in our case all other DTAP environments don’t use a file based MDS, but a database MDS. In the database MDS, we don’t have the file path issues, so there we won’t see this issue. So on all environments except the (local) Integrated WLS, we don’t see these warning logs, and we will see both table personalizations being persisted. It might take you some time to realise this, if you do not want to deploy to Dev or Test without having the Personalization working on your local machine.

Struggle 2: Deploying the application as EAR instead of via JDeveloper


Deploying both from JDeveloper as well as creating an EAR file seems to work. However, there was still some struggle there as well. The personalisation was working when deploying via JDeveloper, but when we would build in EAR from the application via JDeveloper, and deploy it manually to the Integrated WLS via the console, none of the settings were persisted to the MDS, and we saw the following warning in the log files:

     

By opening the application in different browsers again, we can also confirm that neither of customizations the tables is persisted in the MDS now:



When Personalization across sessions with the MDS is configured, JDeveloper always creates a metadata store usages in the adf-config file at deployment time. This configuration is named MAR_TargetRepos.

It does not matter that we have configured a different metadata store usages within the adf-config. If the MAR_TargetRepos is not present while creating the EAR file, it will be added to the adf-config file. The only solution that we found to this, is by naming our metadata store usages to match the expected default, then it will not override or add anything.


      
            
      
 
  
   
    
    
   
  
 


Note that we did not set deploy-target to true, because if we do this, our custom MAR_TargetRepos will be overridden with the default implementation again, when building the EAR file. This default implementation does not contain the FileMetadataStore implementation:



Because we want to override the default MAR_TargetRepos, so the personalization will also work when deploying the EAR instead of deploying via JDeveloper, we do not set the deploy-target to true so the default (false) will be used. In this case the FileMetadataStore configuration will be preserved in the EAR file.

If we deploy the new EAR file, we see the same behaviour as we did when deploying it via JDeveloper. Also, when we use the personalization functions on the screen, we will see files being created within the PersDef folder within the %TEMP% environment variable.

This FileMetadataStore configuration is changed (back) to a DBMetaDataStore configuration by an ANT build script, before deploying on the different DTAP environments instead of the Integrated WLS environment. An example of such ANT script can be found below.


  
  
  
  
 
  
  
  
  
  
 
 
   
   
 
 
  


Be sure that the WLS_HOME environment variable is set in the system environment variables, and the ear.location property is replaced in the ANT file when you want to use the above example.

Struggle 3: Suddenly our application does persisting during the session.


We have configured the adf-config to persist only certain components and attributes across the session. This works very nice and clear, however, suddenly all the other components also persist their state, just not across the session, but during the session.

It is possible that this is not what you want, it certainly was not what we expected or had in mind for our application, but there is nothing much we can do about it. It would have made more sense to turn this off for all the components and only persist those that were configured to be persisted.

Luckily the ADF components have an attribute persist and dontPersist on them. When reading the documentation on these attributes, it sounds exactly like what we need for our application! Before adding the dontPersist attribute to the hundreds of components we have in the application, we decide to test it on a couple. What we found out was very unpleasing, basically these attributes could be used for documentation purpose or for fun, but it certainly did nothing concerning persistence.

We decided to create our own custom class to adjust the framework and get this working. To achieve this, the context-param org.apache.myfaces.trinidad.CHANGE_PERSISTENCE can be adjusted to a custom class.

At first we tried to extend the oracle.adf.view.rich.change.FilteredPersistenceChangeManager class, which is the class ADF uses by default. However, unfortunately this class is declared final. We decided to create a class that extends the org.apache.myfaces.trinidad.change.SessionChangeManager class, and use the FilteredPersistenceChangeManager as an instance variable. This may not be the prettiest solution, but it serves our purpose:
package nl.whitehorses.personalization.changemanager;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import oracle.adf.view.rich.change.FilteredPersistenceChangeManager;

import org.apache.myfaces.trinidad.change.AttributeComponentChange;
import org.apache.myfaces.trinidad.change.ChangeManager;
import org.apache.myfaces.trinidad.change.ComponentChange;
import org.apache.myfaces.trinidad.change.DocumentChange;
import org.apache.myfaces.trinidad.change.SessionChangeManager;

public class CustomChangeManager extends SessionChangeManager {
 private final FilteredPersistenceChangeManager fpcmInstance = new FilteredPersistenceChangeManager();

 @Override
 public void addComponentChange(final FacesContext context, final UIComponent component, final ComponentChange change) {
     if (component == null || component.getAttributes() == null) {
         return;
     }
     final String[] persistArray = (String[]) component.getAttributes().get("persist");
     if (persistArray == null) {
         return;
     }
     for (final String persistVal : persistArray) {
         if (persistVal != null && change instanceof AttributeComponentChange && ("ALL".equals(persistVal) || ((AttributeComponentChange) change).getAttributeName().equals(persistVal))) {
             fpcmInstance.addComponentChange(context, component, change);
         }
     }     
 }

 @Override
 public void addDocumentChange(final FacesContext context, final UIComponent component, final DocumentChange change) {
     fpcmInstance.addDocumentChange(context, component, change);
 }

 @Override
 public boolean supportsDocumentPersistence(final FacesContext context) {
     return fpcmInstance.supportsDocumentPersistence(context);
 }

 @Override
 public ChangeManager.ChangeOutcome addDocumentChangeWithOutcome(final FacesContext context, final UIComponent component, final DocumentChange change) {
     return fpcmInstance.addDocumentChangeWithOutcome(context, component, change);
 }
}

As you can see, the logic for the persist attribute has been implemented in the addComponentChange method. The addComponentChange method from the FilteredPersistenceChangeManager instance, will only be called when the component contains the persist attribute which is set to ALL. Besides the addComponentChange method, all other (public) methods from the FilteredPersistenceChangeManager have been implemented to use the instance variable as well.
Conclusion

After some struggles and adjustments to the implementation and configuration of the application, we got personalization to work in our real world application used by customers. We overcame the struggles, but this was not as easy as the blogs on the internet made us believe beforehand. We hope that sharing this experience, might save you for some of the troubles we had.

To give you some more insight in the code and the struggles, we have created a (simple) demo application AdfPersonalization, to reproduce the issues we had, and which we used to solve them.

This application consists of the default Model and ViewController projects. Also, we added a ViewControllerLibrary project. This ViewControllerLibrary project is imported as a library by the ViewController project.

The AdfPersonalization application can be deployed to Weblogic in multiple ways:

  • Using the ‘Run’ button in JDeveloper.
  • Using Application > Deploy > … to IntegratedWebLogicServer in JDeveloper. This can be done to verify that struggle 2 is no longer an issue.
  • Using Application > Deploy > … to EAR, followed by running the replace-persdef-repo ANT target from the build.xml file. Afterwards the EAR can be deployed to a Weblogic servers, which is capable using a database based MDS. This can be done to verify struggle 1 is no longer an issue.
  • The source of this project can be downloaded via AdfPersonalization.zip.

Resources




Combine WC Portal Assets in one Workspace

Working with WebCenter Portal 12c, you can develop your (Shared) Assets within JDeveloper. After installing the WebCenter updates, you can create an WebCenter Portal Asset Application: 

Choose a more generic application name, in my case RichardWcpAssets:

Now in step two I already know I am going to create a Page Template Asset, so I name the Project RichardPageTemplate and accept the default Project Features:

Accept the default package and location in step three and move on to step 4. In here we actually select the Page Template as Asset Type and choose a Display Name, I decided on RichardPageTemplate again and select finish:

Let JDeveloper generate the files for you, now, next to a Page Template, we would also like to define a Skin for our Portal. However, the WebCenter Portal Asset is an Application, so we have to create a totally new Application, just as we did with the Page Template. We do not care about the application name, so you can just let it be a default, like Application2 in my case:

In step 2 we know that this time we want to create a skin, so I named the project RichardSkin and select next:

Leave the defaults again in step 3 and move on to step 4, here we select Skin as Asset Type and change the Display Name to RichardSkin as well and click Finish:

Now, we have two different Application, but the good thing is all we are really interested in is inside the project structure. So we close JDeveloper and we navigate to the location of the applications on our file system. We can take the RichardSkin project folder and move it into the RichardWcpAssets application folder:

After this there is no use for the temporary Application2 anymore, so we can delete this. Now restart JDeveloper and navigate back to the initial Application, in my case ‘RichardPageTemplate’. Open the application menu and choose Open Project:

Navigate to the Skin project you just moved to the Asset application, select the .jpr file and open it:

Save your changes and you can now edit both your Page Template and your Skin from within the same JDeveloper Application.

Read more about Assets development in the following resources:

Auto Search in the Enterprise Manager through bookmarks

Since 12c when debugging or looking at flow instances in the Enterprise Manager, we have to use the search button to make the flow instances appear. By default the following text is being displayed: 'Conduct a search to display the list of message flows across SOA composites in the SOA Infrastructure'.

When you open the search bar on the right pane and click search, the instances of the last 24 hours are being displayed:

However, there is also a shortcut on this same search pane to 'Generate a bookmarkable link':

If you press this button, a pop-up will be displayed and the generated link will be selected:

Looking at the link, you can see that it holds URL parameters to open the flowInstancesTab and execute the search query. If you copy this link, and paste it in your browser, you will see that it opens the corresponding tab, and start fetching the data:

This means that if you bookmark the URL, from now on you are only one click away from going into the Enterprise Manager, navigating into the flowInstances tab and query the search results:


OOW15: Oracle Open World 2015

Just before Oracle Open World 2015, the launch of the new 12c (12.2.1) release went public. This release was a full release of the whole stack. From WebLogic Server to Business Intelligence, including product that were not on 12.1.3 yet, like WebCenter. A bit closer to Open World than expected, but this was good news, meaning we can talk freely about 12.2.1 and get all the information on it that we want.


Next to the 12.2.1 release, this Open World was about the Cloud, maybe even more than the previous years combined. The Cloud is inevitable and so is the Oracle Cloud, this year, personally I got more positive about the Cloud. A few years ago I was still skeptic, thought this was just a new hype, last year the Cloud still mostly seemed to exist on PowerPoint, but as we speak there are actually quiet some Cloud products live and ready to use.
I do think Oracle oversells the whole story that the Business user will drag and drop and create their own applications, but who knows, they might prove us wrong there as well. None the less, even if it is not for the actual business users, these products can make the lives of the programmers a lot easier as well.
A big announcement that I do want to mention again, is the Private Cloud, I think this is a huge announcement that can change the Cloud plan for a lot of companies. Here in Europe there are a lot of confusing laws and restrictions, that are different per country concerning data and the cloud. As well as there are institution who closely check what is happening with civilian data. Read more about the Private Cloud on my detailed blog post about this.
Next to that I have blogged about Application Builder Cloud Service, the SOA Suite Cloud Service, and a combined blog about microsites with the help of Sites Cloud Service & Document Cloud Service.

One of the "can't miss events" on Open World are always the keynotes, especially those from Larry. If you want to look back at the keynotes, you can find them all on the Open World page. The two quotes from Larry that stuck the most to me were these:
  • ‘Applications shouldn't only be easy to use, but also easy to learn’
  • ‘Security should always be on’
By these principles, Oracle designs there Cloud products as well. They should be easy to learn and easy to use. The line of business user should be able to use the products, not just the IT department, according to Oracle.
Larry explained how a lot of there Oracle products are shipped with good security options, but they are default turned off and you have to turn them on yourself manually. Not in the Cloud, in the Oracle Clouds, security is always on.

Next to the cloud, as a developer I focused on three area's this Open World, you can check out my related findings in the more in depth blogs about: WebCenter Portal, new features in ADF 12.2.1 and Oracle JET.


For an overview of all my Open World 2015 blogs, check this page.

OOW15: Announcing WCP 12.2.1

It has been a long wait, but WebCenter has finally been released on 12c, WebCenter Portal 12.2.1 is out and brings you new features we have been waiting for! Just to name a few:
  • A more/better responsive design
  • a WYSIWYG editor with preview mode
  • Embedded content UI for ECM functionality
  • New Portal REST API
  • Out of the box bootstrap themes
  • A Portal Jump Start kit
  • Cloud Certification (on JCS)

However, there is also a change that might affect you. The Portal Customization Framework as we know it from 11g does not exist anymore. There now is only a Portal Server in 12c. This means you can easily upgrade from your 11g Portal Server to a 12c Portal Server, but if you run on Portal Framework, you will first have to migrate to Portal Server 11g before upgrading to Portal Server 12c.
Oracle does have a whitepaper out on how to migrate from the 11g Framework.

More cool stuff on the roadmap for WebCenter Portal, the product will be tighter integrated with the rest of the WebCenter Suite, as well as with some other Cloud products like JCS, ABCS, SCS, OSN, DCS & PCS. All the different search components will be replaces by the Elastic Search and there will be better performance as well as better performance analyzer tools.
WebCenter Portal will remain on premise for some time, however, as mentioned there is a Cloud certification for JCS, so if you wish you can run it in the Java Cloud Services.

Just as with most of the PaaS Cloud solutions Oracle now offers, you can make changes in contribute mode, they are not directly published and you can even setup an approval process before publication. You can choose whether to publish only the portal, the shared libraries, the content or also the shared assets (like page templates).

Portal still uses the Contextual Event mechanism to communicate with the ADF taskflows. As mentioned the integration with WebCenter Content is way better and you can put annotation on your documents. These annotations are stored separately in WebCenter Content and merged on the document by the viewer.


OOW15: New features in ADF 12.2.1

The whole stack of Fusion Middleware 12c  was launched just before open world. This means there is also a new, cooler and better version of Oracle Application Development Framework (ADF) out! It was not too hard to follow all the session about ADF on open world this year, there were not that many to begin with. 

So what is new? To start with, the infrastructure, we can now use JDK 8 in ADF and WebLogic Server version 12.2.1, which is also Java EE7 complaint. It also fully integrates with the Java Cloud Service (JCS) and the Developer Cloud Service (DevCS). JCS supports ADF version 12.1.3 & 11.1.1.7.1 and you can deploy to JCS directly from JDeveloper. The JDeveloper IDE also fully integrates with the GIT repository on the DevCS. You can track and update tasks and issues:

In ADF Business Components (ADF BC) there is now REST support. You can expose your Application Module as a REST service by simply following a wizard. You can also consume REST services by using the REST Data Control in JDeveloper, it can consume both REST JSON or REST XML. It has a declarative approach, as you would expect from ADF and security supports for OWSM policies.

On the view side, the Alta UI is now enabled by default, there is also a browser based theme editor application. You have a visually modification of the look and feel, create ADF skins and import the jar this application create in your application to use the skin in your ADF application. Next to the skinning, there are more, better and newer Data Visualization Components (DVTs) as well!

There is a cool new feature that allows you to call Remote Regions, this means that you can call a taskflow that is deployed in another application, possible even on a totally different server. Both the consuming as well as the publishing application need to be made aware of these feature. This means that you can reuse taskflows, without the need of consuming a library in the consuming application. The remote region will be loaded parallel (in the other application). You can pass parameters to the region, just like you are used to.

Last but not least, ADF Faces got a lot better at being responsive! They added the so called ‘Masonry Layout’, this is not a new component, but you create responsiveness by adding predefined style classes to your components. ADF now also supports the media tag, with this you can now change properties on your ADF Faces components based on the media query results.

Switch the Audit Level to Development mode

With JDeveloper 12c it is now possible to run your SOA Suite against the Integrated WLS. However, by default the Audit Level of this server is Production mode which means you do not get to see details when looking at the flow trace of your service.
If you do not change your running mode, the flow trace window will look like this:


We will switch the Audit Level of your local SOA domain to Development mode, to get more info in the flow trace. Right click on your soa-infra, go to the SOA Administration and select the Common Properties:



Change the Audit Level to Development and click Apply:



You do not need to restart your server after this. However, you do need to test your service again. Test your service and again go to the flow trace, the result should now look like this:



You can now press the ‘View Payload’ to see the payload of your transformation:




Run ADF & SOA on the IntegratedWLS in separated domains

In JDeveloper 12c, it is possible to run SOA Suite on the InternalWLS, which is a great feature. However, once you have done this, your domain will be filled with SOA extensions. Meaning the server start up time will increase drastically.
When you do both ADF & SOA development, this can be annoying when you just want to run your ADF application and the IntegratedWLS is busy starting up the SOA domain. One way to avoid this is to run two different JDeveloper instances with two different Jdev Homes configure.
In this blog I will describe you how to set this up.

First of all, I got my ‘normal’ JDeveloper for ADF development, this is installed on my C drive, under: C:\oracle\JDev1213, if you navigating to the Oracle_Home\jdeveloper\jdev\bin folder and open the jdev.boot file, you will see the variable ‘ide.user.dir.var’:


Now I recently installed a second JDeveloper 12c in a different directory, this JDeveloper is installed with the SOA extensions, I installed this on the C drive as well, but in the folder C:\oracle\JDevHomeSOA. Within this JDeveloper folder, there is also a jdev.boot file under the folder ‘\jdeveloper\jdev\bin’, however, I changed the ‘ide.user.dir.var’ to a specific _SOA variable:


Now all that is left to do is to create two new Environment Variables, pointing to different JDevHome directories:


This will create two different domains for each JDeveloper, keeping your environment clean and tidy!

Clear ADF 12c deployment on Integrated WLS

Sometimes you want to cancel your Integrated WebLogic Server, however, if you do this while a deployment is currently going on, you might run into trouble. The log window will not tell you anymore than a remote deployment failed and that the Application can not be run:



You need to clear some directories in your JDevHome before the application deployment works again. Before clearing the directories, make sure you close JDeveloper.

Go to the folder: JDevHome\system<versionnumber>\o.j2ee\drs
In here you should see your application that you try to deploy you can delete that folder or you can delete all the folders in this directory. They will be recreated for you when you run the specific application.

Next, go to the folder: JDevHome\system<versionnumber>\DefaultDomain\servers\DefaultServer
In here you should delete the ‘tmp’ folder.

After you deleted the folders, restart JDeveloper and run the application again.
You should now be able to deploy your application again to the Integrated WebLogic Server.


ADF EMG Audit Rules available on JDeveloper 12.1.3

I got a few questions from people why the ADF EMG Audit Rules are not available in JDeveloper 12.1.3. So there has been a new release of the ADF EMG Audit Rules. No new functionality is implemented this time, but the extension is now available for JDeveloper 12.1.3.

If you go to Help -> Check for Updates, tick the Open source and Partner Extensions checkbox and press Next: 

Select the ADF EMG Audit Rules and click Next:

The extension ADF EMG Audit Rules should be installed correctly, click finish and restart JDeveloper 12.1.3:

Now if you go to your Tools -> Preferences, there is a button ‘Manage Profles’ on top of the Audit tab, you will find your profiles under that submenu. Press the button to open the Profiles menu:

Within the Audit Profile, you should see the ADF EMG Audit Rules appear:

ADF EMG Audit Rules 1.0 Released

Today at the UKOUG I showed a new plug-in for JDeveloper 12c together with Wilfred, the ADF EMG Audit Rules. You can find it through JDevelopers Check for Updates in the Help menu. This plug-in is a starting point for creating rules out of the code guidelines document you can find on the ADF Architecture square.


In two previous blogs I showed you how to create audit rules and how to create a fix for your audit rule using the JDeveloper Extension Framework. If you want to get your hands dirty writing some of your own rules, there now is a good starting point for that.


The idea was created during a few sessions with Wilfred van der Deijl creating our presentation, Quality Assurance with the JDeveloper Auditing Framework, for the UKOUG. The goal is to try and create an extension project, to automate ADF coding standards and best practises. The current idea is to use the ADF Code Guidelines document as starting point to create custom rules.


As time is always a critical matter in situations like this, all help is welcome. Anyone who wants to contribute and help us writing code/rules/fixes/etc is welcome to do so. I think it would be a create feature for the whole ADF community if we can write an extension that checks the most common pitfalls already during development.

As we speak we’re still working on an SonarQube plug-in to automate this rules and make them visible in JDeveloper as well as SonarQube.


Resources:
- The ADF EMG Audit Rules project on java.net.
- The ADF EMG on google.
- A thread on ADF EMG about this subject.
- The ADF Architecture Square
- The ADF Code Guidelines v1.00

Uninstall your JDeveloper Extension

Since JDeveloper 12c it’s possible to uninstall extension from your JDeveloper, without deleting jar files and cache directories manually. However, the feature is a little bit hidden, it’s not in your preferences, but in the feature section. You get there through the Tools menu.


Here you can manage your features, check for updates and clear the cache if you want to.

Now if you go to the second tab, installed updates, you get an overview of the updates installed on your JDeveloper.

If you tick for example JUnit, JDeveloper is also smart enough to recognize the dependency. It warns you that you need to uninstall both the bundles.

Next you can click the uninstall button and restart JDeveloper.

That's all it takes to uninstall an extension in JDeveloper 12c.