30 Reusing MAF Application Content with a MAF Shared Library

This chapter describes how to package content, such as task flows, AMX page fragments, and CSS files, into a MAF shared library (shared library) and distribute it to other MAF applications for reuse.

This chapter includes the following sections:

30.1 Introduction to Reusing MAF Application Content with a MAF Shared Library

A shared library lets you share content for reuse with multiple MAF applications.

You can, for example, put a task flow in a shared library from where it can be consumed by multiple MAF applications. Other types of content that can be shared include AMX page fragments, images, CSS and JavaScript files plus HTML pages like the custom launch screen for iOS and the custom login page. A shared library differs from a Feature Archive (FAR) in that the FAR shares application features while you use a shared library to share individual artifacts, such as task flows.

If you want to develop a shared library that other MAF application developers can consume in their applications, use the following workflow:

  1. Create an application using the MAF Application for Shared Library application template. This template provides the required files and directory structure for a shared library and a deployment profile to deploy it. See Creating a MAF Application for Shared Library.

  2. Add the artifacts, such as task flows, which you want to distribute in the shared library. See Adding Artifacts to a MAF Application for Shared Library.

  3. Test your shared library by deploying it and verifying that a MAF application can reuse the artifacts that it contains. See Deploying a MAF Application for Shared Library and Consuming a Shared Library in a MAF Application.

  4. Distribute the ZIP file that contains the completed shared library.

If you want to consume a shared library created by another MAF application developer, create a file system connection in JDeveloper’s Resources window to the directory that contains the extract from the shared library ZIP file that the other MAF application developer distributed. You can then add the shared library to your application. See Consuming a Shared Library in a MAF Application.

30.2 Creating a MAF Application for Shared Library

Add the artifacts that you want to share with other MAF applications to the MAF application for shared library.

Creating a MAF application for shared library is the first step to sharing artifacts with other MAF applications. This creates two projects (ApplicationControllerLibrary and ViewControllerLibrary) and a library-content.xml file where you describe the content of the shared library. Once you create the application for a shared library and the associated projects, perform the following tasks:

30.2.1 How to Create a MAF Application for Shared Library

Create a MAF application for shared library using the application wizard that you invoke from JDeveloper’s New Gallery.

To create a shared library:
  1. In the main menu, choose File and then Application > New.
  2. In the New Gallery, in the Items list, double-click Mobile Application Framework Application for Shared Library.
  3. In the Mobile Application Framework Application for Shared Library wizard, enter application details like the name, directory, and application package prefix. For help with the remaining pages of the wizard, click Help.
    The Project 1 Name page of the wizard shows the list of features needed to complete the ApplicationControllerLibrary project. The Project 2 Name page of the wizard shows the list of features needed to complete the ViewControllerLibrary project.

    Ensure that the value you specify for default package in the Configure Java settings page for each project is unique. Doing so ensures a unique value for the library root directory property and avoids deployment issues for shared library consumers, such as those described in Deploying a MAF Application with Duplicate Shared Library Archive File Names.

  4. Click Finish.

30.2.2 What Happens When You Create a MAF Application for Shared Library

JDeveloper creates a new application with two projects and a variety of other files that these projects require.

Figure 30-1 shows the newly-created MAF application for shared library.

Figure 30-1 Newly-created MAF Application for Shared Library

View of a newly-created MAF Application for Shared Library in the Applications window

Example 30-1 shows the content of a newly-created MAF application for a shared library. It contains two projects (ApplicationControllerLibrary and ViewControllerLibrary) where you add the artifacts that you want to distribute for use with other MAF applications. It also contains a library-content.xml file, which is the file that describes the shared library.

Example 30-1 Content of a Newly-Created MAF Application for Shared Library

MAFappForSharedLib
+---.adf
|   \---META-INF
|           library-content.xml
+---.data
|   ...
+---ApplicationControllerLibrary
|   |   ApplicationControllerLibrary.jpr
|   |
|   +---adfmsrc
|   |   +---application
|   |   |   \---library
|   |   |           DataControls.dcx
|   |   |
|   |   \---META-INF
|   |           adfm.xml
|   |
|   \---public_html
|       \---application
|           \---library
|               \---ApplicationControllerLibrary
|                   \---resources
\---ViewControllerLibrary
    |   ViewControllerLibrary.jpr
    |
    \---public_html
        \---mobile
            \---library
                \---ViewControllerLibrary
                    \---resources

30.2.3 How to Set the Shared Library Root Directory

Set a value for the MAF Library Root Directory project property that will be unique across all projects in shared libraries that a MAF application consumes.

Adopt a naming convention, such as for Java package names, to ensure that the library root directory property is unique. This ensures that your shared library can be consumed by MAF applications that use multiple shared libraries. MAF will not add a shared library to a consuming MAF application if the application already includes a shared library with the same value for the library root directory properties.
To set the library root directory:
  1. In the Applications window, double-click the project for which you want to set the MAF Library Root Directory project property (for example, ViewControllerLibrary).
  2. In the Project Properties dialog, select MAF Library to view the MAF Library page.
    The default value for the MAF Library Root Directory project property is a concatenation of the value for the default package in the Configure Java settings page that you specify when you create the MAF application for shared library and the project name.
  3. Set a unique value for the property, as shown in Figure 30-2, and click OK.

    Figure 30-2 MAF Library Root Directory Property

    Project Properties Dialog Where You Set the MAF Library Root Directory Property

30.2.4 How to Describe the Shared Library Content to Consumers

Use the library-content.xml file to provide information for the consumers of the shared library, such as its version number and a description of any dependencies that they need to be aware of to successfully use the shared library.

An example of a dependency that you should describe in the library-content.xml file is any custom Cordova plugins that the shared library requires because MAF does not package custom Cordova plugins in the shared library. Shared library consumers must obtain required custom Cordova plugins separately.
To describe the shared library content to consumers:
  1. In the Applications Resources panel, expand the Descriptors and ADF META-INF nodes, and then double-click library-content.xml.
  2. In the source editor, add a name for the shared library, a version number, and a description of the shared library’s purpose.
    Example 30-2 shows a library-content.xml file.

Note:

MAF inserts the MAF version that you use to create the shared library into the library-content.xml file when it deploys it.

Example 30-2 library-content.xml File

<library-container 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://xmlns.oracle.com/adf/mf/sharedlibrary"
         name="DocExample">

 <version>2.1</version>
  <library-description>
    This library includes a task flow that enables end users to edit employee details.
  </library-description>
   
</library-container>

30.3 Adding Artifacts to a MAF Application for Shared Library

Add the artifacts that you want to share to the appropriate project in the MAF application for shared library.

The MAF application for shared library template creates two projects (ApplicationControllerLibrary and ViewControllerLibrary). Add resources to the library project that corresponds to the project in a MAF application where the resource will be consumed. For example, the custom HTML page that you add to display an alternative launch screen to the default MAF launch screen on iOS devices is packaged in the ApplicationController project of a MAF application. If you want to distribute this artifact in a shared library, add it to the ApplicationControllerLibrary project within the MAF application for shared library.

In general, use the ApplicationControllerLibrary project to share CSS files, images, and HTML pages, such as a custom login page. Use the ViewControllerLibrary project to share AMX page fragments, task flows, CSS files, images, and JavaScript files.

Make sure that you add the dependencies necessary to use an artifact to the shared library. For example, include login connections and Java classes that underlie a data control. MAF packages these dependencies in the shared library when it deploys the shared library so that they are available to the MAF application that consumes the shared library. One exception is Cordova plugins. MAF does not package Cordova plugins in a shared library. For a Cordova plugin, add an entry describing the dependency to the library-content.xml file, as described in How to Describe the Shared Library Content to Consumers, so that consumers of the shared library know that they need to obtain the Cordova plugin separately from the shared library. Consumers of the shared library can also refer to the jar-maf-plugins.xml file that MAF generates when it deploys the shared library to verify that they have registered all required Cordova plugins in the MAF application.

Use JDeveloper’s New Gallery to create the artifacts that you want to add to the shared library. If, for example, you want to add a MAF login connection to the shared library, invoke the New Gallery and enter “login” in the New Gallery’s search input field to quickly locate the MAF Login Server Connection entry. JDeveloper generates the artifacts and associated files and metadata in the appropriate project. The creation of a login connection in the shared library, for example, results in the creation of a connections.xml file in the ADF META-INF directory of the shared library. Follow this approach for other artifacts that you want to add to the shared library (task flows, AMX page fragments, and so on).

Create all artifacts that you want to share under the library root directory. Note that JDeveloper does not default to the library root directory when you create a task flow or CSS file in a shared library. Navigate to the library root directory or a sub-directory of the root directory to create these artifacts. If you do not do this, the artifacts that you want to share will not be packaged in the deployed shared library. In Figure 30-3, for example, choose the ViewControllerLibrary directory or a sub-directory to create the task flow.

Figure 30-3 Creating a Task Flow in the Library’s Root Directory

Shows the Choose Directory dialog from where you must choose a directory under the Shared library directory in order to create the task flow in a location that will be visible to shared library consumers.

30.4 Deploying a MAF Application for Shared Library

Deploy a MAF application for shared library to test the shared library you created or to distribute a completed shared library to the application developers who will use it in their MAF applications.

Once you deploy a MAF application for shared library, you can distribute it in a ZIP file to other MAF application developers. These developers extract the ZIP and add a file system connection to the extract directory from JDeveloper’s Resources window to consume the shared library in their MAF application. Before you distribute it, you can test your shared library by creating a file system connection to the container directory of the deploy directory (MAFappForSharedLibRootDir/deploy/MafSharedLibraryContainer) in JDeveloper’s Resources window and consuming the shared library in a MAF application that you create for testing. See Consuming a Shared Library in a MAF Application.

MAF provides the following ready-to-use deployment profiles:

  • MafSharedLibraryContainer1

  • ApplicationControllerLibrary_MafSharedLibraryArchive1 to JAR file

  • ViewControllerLibrary_MafSharedLibraryArchive1 to JAR file

Use the above deployment profiles or create your own deployment profile if, for example, you want to customize the deployment options, such as the name of the ZIP file that JDeveloper produces.

It is good practice to verify the file names produced by the deployment profiles are unique and easily distinguishable by the consumers of the shared library. By default, the MafSharedLibraryContainer1 deployment profile names the ZIP file that it produces MafSharedLibraryContainer1.zip. Similarly, the project-level deployment profiles (ViewControllerLibrary and ApplicationControllerLibrary) produce JAR files that append ViewControllerLibrary1.jar and ApplicationControllerLibrary1.jar to the name of the generated JAR files. On the left of Figure 30-4 is the Applications and Resources windows view of a MAF application that consumes two shared libraries (SharedLibOne and SharedLibTwo) with default file names for the generated JAR files and ZIP file. The right of Figure 30-4 shows the MAF Shared Library Container Options page where you can edit the default name for the generated ZIP file. Editing the deployment profiles that generate the ZIP and JAR file names may make it easier for end users to distinguish between shared libraries and avoid deployment issues. For more information about editing deployment profiles, see Working with Deployment Profiles.

Figure 30-4 Shared Libraries with Default File Names and Deployment Profile to Edit Default File Names

Shows default JAR and ZIP filenames generated by MAF’s shared library deployment profiles. Also shows a deployment profile dialog where you can edit these default values.

30.4.1 How to Deploy a MAF Application for Shared Library

Deploy the MAF application for shared library using a MAF Shared Library Container deployment profile that deploys the shared library to a ZIP file.

To deploy a MAF application for shared library:
  1. From JDeveloper’s main menu, select Application, then Deploy, and then MafSharedLibraryContainer1.
    Where MafSharedLibraryContainer1 is the name of the deployment profile.
  2. Select the Deploy to MAF Shared Library Container ZIP file option from the list in the dialog that appears and click Finish.

30.4.2 What Happens When You Deploy a MAF Application for Shared Library

JDeveloper uses the MafSharedLibraryContainer deployment profile to create a ZIP file (default name MafSharedLibraryContainer1.zip) that can contain the following artifacts:

//Contents of MafSharedLibraryContainer1.zip
|   ApplicationControllerLibrary_MafSharedLibraryArchive1.jar
|   ViewControllerLibrary_MafSharedLibraryArchive1.jar
|
\---META-INF
        jar-maf-plugins.xml
        library-content.xml
        MANIFEST.MF
        oracle.adf.common.services.ResourceService.sva

The JAR files in the ZIP contain the resources from each of the respective projects within the MAF application for shared library. However, you should distribute the ZIP file to shared library consumers.

30.5 Consuming a Shared Library in a MAF Application

Create a File System IDE connection to a shared library so that you can reuse the artifacts it contains in your MAF application.

Review the content of the library-content.xml file to determine if there are dependencies that you need to implement to use the shared library successfully in your MAF application. For example, you may need to obtain and register a Cordova plugin in your MAF application. A shared library author should have identified such dependencies in the library-content.xml file before distributing the ZIP file that contains the shared library. You can view the content of the library-content.xml file after you create a File System IDE connection to the shared library’s directory.

Once you have added the shared library to your application, you can use artifacts like AMX page fragments from the shared library in AMX pages of the MAF application that consumes the shared library.

30.5.1 How to Consume a Shared Library in a MAF Application

Add a File System IDE connection to the directory that contains the extract from the shared library ZIP file. This makes the artifacts in the shared library available to consume by your MAF application from JDeveloper’s Resources window.

If you are a shared library author who is testing a shared library, create the File System IDE connection to the child container directory of the deploy directory of the MAF application for shared library (MAFappForSharedLibRootDir/deploy/MafSharedLibraryContainer) and consume it in the MAF application that you created to test the shared library.
To consume a shared library in a MAF application:
  1. In the Resources window, select New, then IDE Connections, and then File System.
  2. Complete the File Systems Connection dialog to create a file connection to the directory that contains the extracted shared library ZIP file. See the Oracle JDeveloper Online help for more information.
  3. Select a project in your MAF application, for example ApplicationController.

    Note:

    If you have multiple ViewController projects in your MAF application, select the ViewController project to which you want to add the shared library resources. If you do not select a ViewController project, MAF adds the shared library resources to the first ViewController project in the Applications window.
  4. Right-click the MAF Library, as shown in Figure 30-5, and select Add to Application.

    Tip:

    You can remove a shared library from a MAF application by selecting the same directory and choosing the Remove from Application option that will be enabled when a MAF application consumes a shared library.

    Figure 30-5 Shared Library in JDeveloper's Resources Window

    Shows the Add to Application context menu entry that appears when you right-click the shared library node in the Resources window.
  5. Use the appropriate dialog picker(s) from within the MAF application to reference the resources from the shared library that you want to use in the MAF application.
    1. To reference an AMX page fragment from a shared library, add an AMX page fragment to your AMX page and set its src attribute to the location of the page fragment in the shared library, as shown by Figure 30-6.

      Figure 30-6 Using an AMX Page Fragment from a Shared Library

      Shows the Edit Property dialog that appears when you modify a property.
    2. To use a task flow from a shared library, you can reference it from the Content tab of the maf-feature.xml file’s overview editor or add a task flow call activity to a task flow.

      To reference it from the Content tab of the maf-feature.xml file’s overview editor, click on the Browse icon in the Content tab of the maf-feature.xml file’s overview editor and navigate to select the task flow from the shared library, as shown by Figure 30-7.

      Figure 30-7 Using a Task Flow from a Shared Library

      Shows how you select a task flow from a shared library by clicking the Browse icon beside the File input field in the Content view of a MAF Task Flow application feature.

      To use a task flow call activity, add the task flow call activity to your task flow and use the Edit Property dialog that you invoke from the Properties window to navigate to the task flow in the shared library, as shown by Figure 30-8.

      Figure 30-8 Calling a Task Flow from a Shared Library with a Task Flow Call Activity

      Shows how you call a task flow from a shared library by using a task flow call activity.

One use case where you cannot use dialog pickers is to reference images from a shared library in a CSS file in your MAF application. Reference the image(s) using a relative file path from the current CSS file to the image file in the shared library.

To construct the relative path, navigate from the current CSS file to the Web Content folder (the public_html on your file system). Then append the value of the shared library project’s library root directory property and any additional sub-directories plus the file name of the image that you want to reference.

Figure 30-9 shows an example where you reference the ac_img.png image file in an image sub-directory of a shared library project that has a library root directory property of apppackprefix/application/library/ApplicationControllerLibrary. The CSS file that references the image is two directories away from the public_html directory. As a result, the relative file path that you use for the image in the CSS file is the following:

"../../apppackprefix/application/library/ApplicationControllerLibrary/image/ac_img.png"

Tip:

Select View > Application Projects > Show Libraries in JDeveloper to view the shared libraries in the Applications window, as shown in Figure 30-9.

Figure 30-9 Referencing an Image from a Shared Library in a CSS File

Illustrates how you specify a relative path in a CSS file to an image in a shared library.

30.5.2 What Happens When You Consume a Shared Library in a MAF Application

MAF adds the content of the ApplicationControllerLibrary project from the shared library to the ApplicationController project in the MAF application. Similarly, the content of the ViewControllerLibrary project from the shared library is added to the ViewController project in the MAF application.

MAF adds the JAR files in the shared library to the consuming MAF application. You can view these JAR files in the consuming MAF application’s Applications window, as shown by Figure 30-10. Select View > Application Projects > Show Libraries in JDeveloper to view these libraries.

Figure 30-10 Shared Libraries in a Consuming MAF Application

Shows the JAR files that appear in the Projects panel when you select Show Libraries in JDeveloper’s View, Application Projects menu.

MAF will not add the shared library to the MAF application if the shared library was created with a different version of MAF to the version that you are currently using to develop your consuming MAF application. That is, a shared library developed with release 2.4.0.0.1 will work with a MAF application developed with release 2.4.0.0.2, but not with release 2.4.0.1.1. Shared library authors need to upgrade the shared library to support the release of MAF that you use to build your consuming MAF application. MAF will also not add the shared library to the MAF application if its existing library root directory matches the library root directory of an existing shared library in use by the MAF application. For information about changing the value of a shared library root directory, see How to Set the Shared Library Root Directory.

Connections that you define in the shared library are merged with connections in the MAF application that consumes the shared library. MAF adds a comment, similar to the following example, that identifies each connection that it adds to the MAF application’s connections.xml file from the shared library.

<!--
 The following connections were added by MAF Shared Library 'DocExample': test 
-->

The comment identifies the source of the connection and the name of the connection. In the previous example, 'DocExample' refers to the name of the shared library, the value that is specified for the name attribute in the library-content.xml file, and test refers to the name of the connection. If no value is specified for the name attribute in the library-content.xml file, MAF uses the name of the container ZIP (for example, MafSharedLibraryContainer1). This comment can be useful in helping you to identify connections that you can remove from the MAF application’s connections.xml file if, for example, the MAF application no longer uses the shared library that led to the merge of the connection into the connections.xml file or, as discussed later, you want to upgrade to a newer version of the shared library. JDeveloper also displays a message in its Log window that identifies the connections added from the shared library and if further configuration is required before the connection can be used, as shown by the following example:

[04:42:06 AM] These connections were added by the Add to Application operation.
[04:42:06 AM] {
[04:42:06 AM]    test - new, incomplete LoginConnection connection will be added. Configure before use.
[04:42:06 AM] }

If MAF encounters duplicate connections defined in the shared library and in the consuming MAF application, it will not merge connection information from the shared library and removes the shared library from the MAF application. The consuming MAF application’s connections.xml file remains unchanged. For the scenario where you want to upgrade to a newer version of the shared library that your MAF application consumes, remove the pre-existing connections from your MAF application or coordinate with the shared library author to remove the pre-existing connections from the shared library so that MAF does not prevent the upgrade due to the existence of duplicate connections in the MAF application and the shared library.

30.6 Deploying a MAF Application with Duplicate Shared Library Archive File Names

Describes how to deploy a consuming MAF application with shared libraries that use the same file names for the JARs that package the shared library content.

Assume that you have a consumer application that consumes two shared libraries (SharedLib_One and SharedLib_Two). These shared libraries have unique values for the root directory property. For example, test/mobile/library/ViewControllerLibrary_SharedLib_One is the value for the ViewControllerLibrary project of the SharedLib_One shared library. The values for the root directory in the other projects are similarly unique in that they append the name of the shared library application (SharedLib_One or SharedLib_Two). However, the author of these shared library applications chose the same value (test) for Application Package Prefix when creating both shared libraries.

The files names for the ZIP and JAR files that the deployment profiles of these shared libraries generate are left to the default values, so both shared library applications are packaged in ZIP and JAR files with the same file names:

|   MafSharedLibraryContainer1.zip
...
    |   test_application_library_ApplicationControllerLibrary1.jar
    |   test_mobile_library_ViewControllerLibrary1.jar

As each project within both shared library applications has a unique value for the root directory property, the consumer application can successfully add the two shared libraries. However, an attempt to deploy the consumer application after adding the two shared library applications fails with the following message appearing in JDeveloper’s Log window.

[11:45:00 AM] ----  Deployment started.  ----
...
[11:45:07 AM] Deployment cancelled.
[11:45:07 AM] ----  Deployment incomplete  ----.
[11:45:07 AM] Failed deployment to Android emulator. Encountered exception: Cannot deploy the 
              MAF Shared Libraries included in the application because one or more MAF Shared Library 
              archive files have the same name and are configured to be included in the same archive 
              destination directory.

Deployment fails because the project-level FAR deployment profiles invoked by the application-level deployment profile package the shared library JARs within a lib directory in the generated deployment JAR. This is ViewController_MobileFeatureArchive1.jar in the case of a ViewController project. When MAF encounters two shared library JARs with identical file names, it stops the deployment rather than overwrite one shared library JAR with another in the lib directory.

The above scenario could have been avoided if the shared library authors adopted a unique naming convention for the Application Package Prefix value when they initially created the shared libraries or edited the deployment profiles to generate file names other than the default values shown above. You (the application developer for the consuming MAF application) can work around this issue and successfully deploy your application by editing the project-level FAR deployment profile to create a second directory (for example, lib2) where MAF packages the second shared library JAR that has the same file name. This configuration change results in a successful deployment where MAF packages both shared library JARs in the following directory structure inside the project-level deployment JAR. The following example assumes a deployment to Android for the ViewController project.

ViewController_MobileFeatureArchive1.jar
        +---lib
        |   |   test_mobile_library_ViewControllerLibrary1.jar
        +---lib2
        |   |   test_mobile_library_ViewControllerLibrary1.jar
        +---META-INF
        ...
        |
        \---public_html
        ...

Perform this configuration change for both the ApplicationController and ViewController project-level deployment profiles.

To edit the project-level deployment profile:

  1. In the Applications window, double-click the project and select the Deployment node in the Project Properties dialog that appears.

  2. Select the deployment profile for the project and click the edit icon to open its properties dialog.

    The default name is ProjectName_MobileFeatureArchive1 (MAF Feature Archive).

  3. Select the File Groups node in the dialog that appears and click New.

  4. In the Create File Group, enter a name, for example Libraries2, select the Libraries radio button, and then click OK.

  5. In the newly-created Libraries2 file group, set the Target Directory in Archive property to a unique value (for example, lib2).

  6. In the Contributors node, clear the check box for the first library.

  7. In the Contributors node for the first Libraries file group, clear the check box for the second library, as shown in Figure 30-11.

    Figure 30-11 Creating a Second File Group Library Definition for a Shared Library Archive with Duplicate File Names

    Shows a project-level deployment profile where you add a second library definition to accommodate a second shared library that is packaged in archive files with the same file names as an existing shared library.
  8. Click OK to close the dialogs and click Build > Clean All and Refresh Application prior to deploying your MAF application again.

30.7 Using Cordova Plugins in Shared Libraries

A deployed shared library does not include the Cordova plugins that it uses. You must obtain the Cordova plugin separately from the shared library and register it in the consuming MAF application.

MAF packages a modified copy of the maf-plugins.xml file with a filename of jar-maf-plugins.xml file in the META-INF directory of the shared library. It sets the path attribute to an empty string for all Cordova plugins in the jar-maf-plugins.xml file. The content of the jar-maf-plugins.xml file is not merged with the consuming MAF application’s maf-plugin.xml file when a MAF application consumes the shared library. Use the jar-maf-plugins.xml file to verify that you have registered all Cordova plugins that the shared library requires in the consuming MAF application’s maf-plugins.xml file.

For more information about Cordova plugins, see Using Plugins in MAF Applications.