Skip Headers
Oracle® Fusion Middleware Developer's Guide for Oracle JDeveloper Extensions
11g Release 2 (11.1.2.1.0)

Part Number E20067-02
Go to Documentation Home
Home
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

1 Introduction to Developing Oracle JDeveloper Extensions

Developing extensions to the JDeveloper integrated development environment (IDE) lets you add additional features to JDeveloper.

The following sections provide an overview of using and developing JDeveloper extensions:

1.1 About Developing Oracle JDeveloper Extensions

Oracle JDeveloper is an integrated development environment (IDE) for building applications using the latest standards for Java, XML, Web services, and SQL. Most of the basic functionality in JDeveloper is implemented as extensions—software packages which add features and capabilities to the basic JDeveloper IDE. You can add existing extensions into JDeveloper, or you can build on JDeveloper's native functionality by creating extensions to provide new features tailored to your organization's development requirements, for example:

There are a wide variety of extensions readily available for you to download and use. Some of these have been developed by Oracle, and some by third parties. These provide new features to JDeveloper and integrate it with other applications that are used by customers in their own development environments. For example, many of the version control and teamworking systems available in JDeveloper are written and distributed as extensions. The open architecture of JDeveloper means that you can download and install them from Check for Updates on the JDeveloper Help menu. Alternatively, you can install them from the Oracle JDeveloper Extensions page on the Oracle Technology Network (OTN) at http://www.oracle.com/technetwork/developer-tools/jdev/index-099997.html.

Note:

The recommended way of installing extensions to JDeveloper is to use Check for Updates on the JDeveloper Help menu because only extension versions that match the version of JDeveloper you are using will be available.

For more information, see "Working with Extensions" in Oracle Fusion Middleware User Guide for Oracle JDeveloper.

This same open architecture also makes it possible for you to write your own extensions if you have specific needs or you would like to integrate JDeveloper with some external process or tool that your development team uses. You can add menu items, create context menus, integrate features into the JDeveloper toolbar, create dockable windows that provide a view into your data objects, and more.

Note:

The way that JDeveloper handles extensions has changed in Oracle JDeveloper 11.1.2.nn. For information about extensions for earlier versions of JDeveloper, see the online help in your version of JDeveloper.

Oracle extensions for earlier versions of JDeveloper, including the Extension SDK, and third-party extensions for earlier versions of JDeveloper are available from the Oracle JDeveloper Extensions page at http://www.oracle.com/technetwork/developer-tools/jdev/index-099997.html.

Information about migrating extensions written for earlier versions of JDeveloper is in Section 1.5, "Migrating Extensions from Previous Releases."

You can use JDeveloper's native features to develop your own extensions. For more information, see Chapter 2, "Developing Extensions in Oracle JDeveloper."

For more advanced development, the JDeveloper Extension Software Development Kit (Extension SDK) has been developed by the JDeveloper development team. It includes a collection of projects containing sample code, and the javadoc-generated documentation for the Extension SDK API which provides reference for classes and other features used in extension development. It is available from Check for Updates on the JDeveloper Help menu, and it contains much more complete documentation and examples. If you are planning to do serious extension development, either to provide wide support to an internal team or to develop an extension as part of a product or third-party application to pass on to your own customers, it is highly recommended that you download the Extension SDK. For more information, see Chapter 3, "Developing with the Extension SDK."

You can use the Oracle JDeveloper page on the OTN forum to ask a question about developing an extension, contribute to a discussion, or interact with other users. The Oracle JDeveloper page on the OTN forum is located at http://forums.oracle.com/forums/forum.jspa?forumID=83.

In contrast to the Extension SDK, JDeveloper also allows you to use external tools without any coding:

For more information about External Tools, see "Adding External Tools to JDeveloper" in Oracle Fusion Middleware User Guide for Oracle JDeveloper.

1.2 Developing Extensions with OSGi

The Open Services Gateway Initiative (OSGi) is a specification for building service platforms running on top of a Java Runtime environment. JDeveloper is built as a set of extensions which conform to OSGi, and any extensions that you write must also conform to this standard.

For more information about OSGi, see the OSGi Service Platform Core Specification Release 4, Version 4.2 which is available from http://www.osgi.org.

The OSGi Framework can be divided into two main elements, both described below:

1.2.1 Service/Component Platform

The Service/Component Platform allows an OSGi implementation to activate, de-activate, update and de-install existing services and to install new services dynamically.

The Service/Component platform supports the interaction between 3 actors:

  1. Service providers, which provide specific services and publish service descriptions.

  2. Service requesters, which discover services and bind to the service providers.

  3. Service registry, which manages the publication and discovery of services based on the registered service descriptions.

An OSGi service is a Java class or interface (service interface), along with a variable number of attributes (service properties), which are name and value pairs. Service properties allow differentiation between service providers which use the same service interface.

The service registry allows services to be discovered by service requesters using LDAP.

Service requesters can receive events signalling changes, for example, publication or retrieval of a service in the service registry, using notification mechanisms.

1.2.2 Deployment Infrastructure

Services are packaged into service bundles which contain service implementation classes and resources, along with the manifest file manifest.mf which contains the bundle metadata. The manifest file contains information such as the service name, version and dependencies.

Service providers and service requesters are part of a service bundle that is both a logical and a physical entity. The bundle is responsible for run-time service dependency management activities which include:

  • Publication

  • Discovery

  • Binding

  • Adapting to changes resulting from the dynamic availability—the arrival or departure—of services that are bound to the bundle.

When you create an extension in JDeveloper, it is composed into an OSGi service bundle.

1.3 How JDeveloper Extensions Work

This section describes the essential features of how extensions work in JDeveloper. In order to help with startup performance, overall memory use, and how JDeveloper performs day to day, only extensions that the user is using are loaded. Some terms and concepts that you may be unfamiliar with are described below:

1.3.1 How Extensions are Processed

There are two distinct phases to the way that JDeveloper processes extensions:

  • Extension registration. This happens as JDeveloper starts up. It involves registering all extensions available for the selected role. No extension code is executed except for those extensions required to start JDeveloper.

  • Extension initialization. This happens at any time the user accesses a functional area registered by an extension during the extension registration phase. Therefore you can see that an extension can be initialized at any time when JDeveloper is being used.

1.3.2 Registering Extensions and Using Trigger Hooks

Extension registration is the JDeveloper IDE startup phase during which the extension registry processes the <trigger hooks> section of the extension manifest extension.xml from all extensions available. During this processing no extension-specific code is executed with the exception of translatable resources such as Java resource bundles.

Extensions can define extension specific trigger hooks using the <trigger-hook> integration hook. If they do so, they must use the oracle.ide.extension.HashStructureHook handler since the IDE will not execute extension specific code unless that extension is initialized. The extension specific trigger hook data will be available for retrieval in the Extension Registry. The extension owning the trigger hook can retrieve that data once that extension is initialized. For more information, see Section 2.5.1, "How to Register a <trigger-hook-handler>."

By contrast, other items that do not belong in the <trigger hooks> section of the extension manifest extension.xml are initialized declaratively in the initialization phase of the extension.

There are two types of trigger hooks, system and custom, and every extension is initialized by:

  • Being called from a system trigger hook

  • Being called from a custom trigger hook

  • Being explicitly initialized by another, already initialized, extension

The types of trigger hook defined by the JDeveloper IDE are:

  • Menus: Only menus that qualify as an entry point to an extension should be menu trigger hooks, and menus that are used to support an already initialized extension should not be trigger hooks. For example, in the JDeveloper View menu, the Breakpoints menu item is a trigger hook since a user will want to set breakpoints before running the debugger, but the debugger subMenu in the View menu is not a trigger hook since everything in it is only used once the extension is initialized. From this you can see that menu items for uninitialized extensions are not visible in JDeveloper.

  • Context Menus: Extensions can create custom trigger hooks that use context menus as the trigger. There are no system-level context menu trigger hooks.

  • IDE Actions and Controllers: Only actions and controllers to support menu trigger hooks should be registered. All other actions and controllers should execute in the initialization phase. Any controller registered for a trigger hook menu will not be able to run code to determine if their menu is disabled or not; it must use declarative controller logic to specify when the menu is shown.

  • Gallery Items: Extensions can list items in the JDeveloper New Gallery using the gallery item trigger hook. When the user opens a dialog or wizard from the New Gallery it causes the extensions for that item to initialize, and any extension marked as a dependency in the OSGi bundle manifest of this extension is also loaded.

  • Technology Scopes: When a technology scope is added to a project, the extension that registered that technology scope is initialized, along with any other extension marked as a dependency in the OSGi bundle manifest.

  • NodeFactory Recognizers: This allows extensions to identify the nodes they own. When a node becomes visible in a navigator, if the extension for that node is registered, it will be initialized. NodeFactory recognizers also handle things like dragging a file from the desktop into JDeveloper.

  • IDE Preferences/Settings, Application Preferences/Settings, Project Preferences/Settings: Uninitialized extensions will only show as a category listing in the Preferences dialog (available from the Tools menu). It is not until a user clicks on the category that they will be asked if they want to initialize the extension at that point.

  • Singleton Registration: Singleton classes register as a trigger hook. When a client requests a service from a singleton, the framework will check to see if that singleton's extension has been initialized. If it has not, it will call for the extension to be initialized. An example is the Log Manager.

  • Annotations: Extensions can register themselves as needing an annotation trigger hook. They list out the annotation class names and when the user types one of those annotations, we will initialize that extension at that time. The annotation trigger hooks are used during navigator node expansion to determine icon overlays. When a parent node is expanded, the framework will look for any annotations that are registered and if found, will supply the appropriate icon for that node. The extension will not be initialized in the case where the node icon overlay is applied.

  • Application and project migrators: These migrators must be defined declaratively. Migrators specify the current versions supported. If the application or project file lists an older version of the migrator, or no version at all, JDeveloper triggers the initialization of the extension in order to perform the migration of that extension's data.

  • Library and Tag Library: When a library or tag library is added to a project, the associated extension will trigger to initialize. In addition to this, when a project is opened (not loaded), JDeveloper looks for libraries of that project and automatically loads the extensions that are associated with that library or tag library if they are not already loaded.

  • Custom Trigger Hooks: An extension can define its own trigger hook. This is useful for the situation that an extension wants to allow clients to plug into it. An extension defines its trigger hook in the same manner that it defines a regular hook. Client extensions can then add a trigger hook registration (either system or custom) into their extension manifest. When registering a trigger hook, the extension specifies which extension(s) need to be loaded in order for the trigger to take effect. These are called hook dependencies. JDeveloper ensures that this hook is only processed when all the extensions listed as hook dependencies are initialized.

1.3.3 How Lazy Initialization Works

In order to avoid initializing all extensions every time JDeveloper starts lazy extension initialization is used.

  • During JDeveloper startup, the IDE only executes Addin.initialize() code if the extension that owns the Addin has been previously used by the end user in the currently opened application or project. For more information, see Section 2.2.4, "Understanding Node Recognizers."

  • Each extension identifies a type associated with their trigger hook so that this hook:

    • Can only be triggered when there is an application workspace open.

    • Can only be triggered when there is a project open.

    • Can be initialized at any time in the way that, for example, the HTTP Analyzer can be.

  • As users work on an application in JDeveloper, the user's usage of extension functionality is recorded in a project-specific extension initialization list. That way, when the user stops working on a project by exiting JDeveloper and re-starting at a later time, JDeveloper only initializes the extensions listed in the project's initialization list.

    For extensions that do not require a project, the information is stored in the IDE preferences for the user.

When you are developing your extension you need to consider how the integration points deal with lazy initialization. For example:

  • Extensions cannot assume that integration points are static; extensions must be ready at any time during their life cycle to process and integrate new data associated with their integration point.

    For example, extension A has an API or a custom extension hook that allows other extensions to register some listener class. Extension A cannot assume that all such listeners are registered by the time extension A is initialized; other extensions that depend on A can be lazy initialized later in the life cycle of ABC. Therefore, extension A must update its event firing code associated with these listeners to deal with this effect of extension lazy loading. The way this is done is described in the next point.

  • Extensions should use oracle.ide.extension.HashStructureHook to implement custom integration hooks. This hook processing class has a property change listener mechanism that lets clients know when new additional data is registered. Your extension should listen for these property change events.

  • You should avoid having a deep dependency tree because having extensions with deep dependency trees, What will happen is that the extension will cause the initialization of all the extensions it depends on, which can diminish the performance gains of lazy extension loading. If you find that your extension has a deep dependency tree, you need to refactor the extensions to reduce the number of extensions it depends on. For more information, see Section 2.2.6, "Understanding Large Extensions."

1.4 Guidelines for Writing JDeveloper Extensions

This section is an outline of good development practice for JDeveloper extensions.

You can find more information to guide you in Section 2.2, "Use Cases for Developing Extensions."

1.5 Migrating Extensions from Previous Releases

If you have an extension that you developed for an earlier version of JDeveloper, you will need to change it to run in the current release of JDeveloper. Section Section 1.3, "How JDeveloper Extensions Work" describes how extensions now work in JDeveloper, so you should start by being familiar with the concepts described there.

The coding areas you need to consider are:

There are a number of use cases in Section 2.2, "Use Cases for Developing Extensions" that describe situations you may encounter when you are converting your extensions to use declarative trigger hooks support lazy initialization.

1.6 Getting Started With Extension Development

Whether you use the native features of JDeveloper to create an extension, described in Chapter 2, "Developing Extensions in Oracle JDeveloper," or download the Extension SDK to develop an extension, described in Chapter 3, "Developing with the Extension SDK," you start by creating an application in JDeveloper along with one or more projects configured for extension development.

1.6.1 How to Create an Application and Project for Extension Development

An application is the control structure for one or more projects. A project is a logical container for a set of files that defines a program or part of a program. For more information, see "About Working with Applications and Projects" in Oracle Fusion Middleware User Guide for Oracle JDeveloper.

To create an application and project:

  1. Open the New Gallery by choosing File > New.

  2. In the New Gallery, in the Categories tree, under General select Applications.

  3. In the Items list, double-click Custom Application. The Create Custom Application wizard opens. For help with the wizard, press F1 or click Help.

  4. Enter a name for the application and choose a location and an application package prefix and click Finish.

    The application is created with a default project called Project1 that you will not use and can delete.

  5. Next, create a project that is configured for extension development. Open the New Gallery by choosing File > New.

  6. In the New Gallery, in the Categories tree, under Client Tier select Extension Development.

  7. In the Items list, double-click Extension Project. The Create Extension Project dialog opens. For help with the dialog, press F1 or click Help.

  8. Enter a name and other details for the extension project. When you are done, click Finish.

The extension project is created in the Application Navigator, and contains the elements shown inFigure 1-1.

Figure 1-1 Extension Project in the Application Navigator

Extension project

The extension project is created, along with a copy of the extension manifest extension.xml and the OSGi manifest manifest.mf. The extension manifest is opened in the overview editor.

1.6.2 How to Develop for a Different JDeveloper Version

If you are developing an extension for a different version of JDeveloper, you choose the platform when you create the Extension project.

Note:

You can only develop extensions for other versions of JDeveloper 11.1.2.0.0.

When you create the extension project, as in Section 1.6.1, "How to Create an Application and Project for Extension Development", when you have the Create Extension Project dialog open (step 7), click Manage to open the Manage Extension Platforms dialog.

In this dialog, enter details of the JDeveloper version that you are developing the extension for. For more help, press F1 or click Help in the dialog.

1.6.3 How to Create an Empty Extension Project

If you are familiar with creating extensions, and want to start with an empty project, you can create a custom application with a project that is set up for extension development but which does not contain the extension manifest extension.xml and the OSGi manifest manifest.mf.

To create an extension application with an empty project:

  1. Open the New Gallery by choosing File > New.

  2. In the New Gallery, in the Categories tree, under General select Applications.

  3. In the Items list, double-click Custom Application. The Create Custom Application wizard opens. For help with the wizard, press F1 or click Help.

  4. Enter a name for the application and choose a location and an application package prefix.

  5. Click Next, and enter a name for the project. On the Project Features tab, select Extension Design Time and shuttle it to the Selected list, then click Finish.

In this case, an empty project is created in the Application Navigator, and you need to create extension.xml separately in the same way that you would create any XML file. For more information, see "Creating XML Files in Oracle JDeveloper" in Oracle Fusion Middleware User Guide for Oracle JDeveloper.

1.6.4 Next Steps

Once you have created an application and project you can begin to develop the extension:

1.7 Working with the Extension Manifest

The extension manifest, extension.xml, controls many aspects of the extension. Before you can deploy an extension, you must complete extension.xml to, for example, register trigger hooks. There can only be one extension.xml per project, and it must always be in a directory called meta-inf.

The extension manifest conforms to the JSR-198 specification, which is available at http://jcp.org/aboutJava/communityprocess/final/jsr198/index.html.

Hooks and trigger-hooks are set in the relevant sections of the extension manifest. The <hooks> section of extension.xml is processed when the extension is initialized. The <trigger-hooks> section is processed when JDeveloper starts up.

JDeveloper has a dedicated overview editor for extension.xml, illustrated in Figure 1-2.

Figure 1-2 extension.xml in Overview Editor

extension.xml in overview editor

You edit extension.xml using the overview editor, where you enter information such as details about dependencies into fields, and choose from lists of available objects, and where you can use the Structure window and Property Inspector. To edit information in extension.xml that is not available in the overview editor, you can either use the Structure window or work in the extension.xml source, which you access by clicking the Source tab.

For more information about dependencies, see Section 1.8.1, "Understanding Dependencies."

The template code for extension.xml created by creating an extension project contains placeholders for the main elements, shown in Example 1-1.

Example 1-1 Template Code in extension.xml

<extension id="yourcompany.extension" version="1.0" esdk-version="1.0" rsbundle-class="yourcompany.extension.Res"
           xmlns="http://jcp.org/jsr/198/extension-manifest">
  <name>${EXTENSION_NAME}</name>
  <trigger-hooks xmlns="http://xmlns.oracle.com/ide/extension">
    <!-- TODO Declare triggering functionality provided by extension: yourcompany.extension -->
    <triggers/>
  </trigger-hooks>
  <hooks>
    <!-- TODO Declare functionality provided by extension: yourcompany.extension  -->
  </hooks>
</extension>

1.7.1 Editing the Extension Manifest in the Overview Editor

On the General tab of the overview editor for extension.xml you enter information about the extension such as the extension name, the SDK version, and specify features such as an icon and copyright information. This information populates the feature-hook and platform-info elements.

The Dependencies tab is where you can specify that this extension is part of another extension, or alternatively specify that this extension is parent to another extension. This populates the dependencies element. The Hooks tab is where you details of additional extensions to contribute functionality to your extension. For more information, see Section 1.8.1, "Understanding Dependencies."

Detailed help, which describes the content of each field, is available by pressing F1 from any tab in the overview editor.

1.7.2 Editing the Extension Manifest in the Source Editor

You edit the extension manifest in the source editor using the XML editor, a specialized schema-driven editor which includes a number of editing features including Code Insight and XML validation. For more information, see "Using the XML Editors" in Oracle Fusion Middleware User Guide for Oracle JDeveloper.

1.8 Working with the OSGi Manifest

The OSGi manifest, manifest.mf, lists the packages that the extension bundle exports. There can only be one manifest.mf per project, and it must always be in a directory called meta-inf.

When a new extension project is created, a default manifest.mf is created, as shown in Example 1-2.

Example 1-2 Default of manifest.mf

Manifest-Version: 1.0Bundle-ClassPath: .

For detailed information about the content of the OSGi manifest, see http://www.osgi.org/javadoc/r4v42/overview-summary.html.

As part of the packaging process for an extension, JDeveloper updates manifest.mf to provide:

These values are set in the OSGi Bundle Profile dialog. For more information, see Section 5.2.1, "How to Create the Deployment Profile."

1.8.1 Understanding Dependencies

Extensions can depend on other extensions or JAR files. When you are developing extensions for JDeveloper, you need to understand the dependencies upon the extension, as well as the extension tree. You need to know the dependencies between your extension and other extensions, that is whether:

  • Your extension is part of another extension

  • Or, one or more extensions are part of your extension

You also need to know the libraries and JAR files that need to be added. For example, if you add a dependency on oracle.jdeveloper.maven.jar, you must also add dependency libraries for those JAR files delivered with the external Maven module.

Once you have worked this out, you set dependencies in the extension manifest, and ensure that any libraries and additional JAR files are part of the extension bundle.

1.8.1.1 How to Set Dependencies in the Extension Manifest

When you create an extension project, the extension manifest is created and opened in the overview editor. For more information, see Section 1.7, "Working with the Extension Manifest."

The order in which extensions are loaded depends on the entries in the extension manifest.

To set dependencies in the Extension Manifest:

  1. In necessary, open extension.xml in the overview editor by double-clicking on extension.xml under META-INF in the Application Navigator. Select the Dependencies tab.

  2. To specify that other extensions are dependent on this extension, click Add Extension Import. In the Select Extension dialog, choose one or more extensions and click OK.

    For more help at any time, press F1 or click Help from the dialog.

    The extensions you select as listed as <import> elements in the <dependencies> section of the extension manifest.

  3. To specify extension requires classes from another OSGi bundle, click Add Bundle Entry. In the Select Required Bundles dialog, choose one or more bundles that depend on this extension and click OK.

    The extensions you select as listed as <bundle> elements in the <required-bundles> section of the extension manifest. When searching for a class, OSGi will search in the order they are listed, so be sure to add the bundle to the proper location in the list of bundles.

1.8.1.2 How to Set Dependencies in the OSGi Bundle Profile

As part of packaging up your extension, you create an OSGi bundle profile which is used to determine the generated bundle manifest. For more information, see Section 5.2.1, "How to Create the Deployment Profile."

The important entries to make on the OSGi Bundle Profile dialog are:

  • Package Exports: This is where you specify file groups that are contributors to the Export-Package section of the generated bundle manifest. For example, if there are Java packages in your extension which you want to make accessible to other extensions, list the packages in this section.

  • Package Imports: This is where you specify file groups, library dependencies, and profile dependencies that are contributors to the Import-Package section of the generated bundle manifest.

  • Require Bundle: This is where you specify library dependencies and profile dependencies that are contributors to the Require-Bundle section of the generated bundle manifest.

The Library Dependencies page allows you to check the library dependencies for the bundle, and the Profile Dependencies page allows you to examine and if necessary change dependencies on other JAR deployment profiles in the application.

1.8.1.3 Duplication Between extension.xml and manifest.mf

If you edit the OSGi manifest by hand rather than letting JDeveloper create it as part of the Deployment process, you can enter similar information about the extension in the extension manifest extension.xml and in the OSGi manifest manifest.mf, for example:

extension.xml manifest.mf
<dependencies> Required-Bundles
<extension-id> Bundle-SymbolicName

Where there is duplication, the information in manifest.mf is used, however the extension load order is always taken from the <dependencies> section of extension.xml.