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 Extensions implement the most of the functionality in the 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 requirement.

A few of the functionalities include:

  • To streamline your work flow.

  • To use a third-party team development tool.

  • To use software packages unique to your team.

  • To help implement development standards and best practices with audit extensions.

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 team working 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 extensions:


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.

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.


The way that JDeveloper handles extensions 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 Migrating Extensions from Previous Releases.

You can use JDeveloper's native features to develop your own extensions. See Developing Extensions in 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. See 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 https://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:

  • You can invoke command line interfaces

  • You can pass parameters

  • You can add menus to JDeveloper

For information about developing extensions for JDeveloper, see "Working with Extensions" in Developing Applications with Oracle JDeveloper.

For information about External Tools, see "Adding External Tools to JDeveloper" in Developing Applications with Oracle JDeveloper.

1.2 Developing Extensions with OSGi

JDeveloper Extensions conform to the Open Services Gateway Initiative (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:

  • Service/Component Platform, that is the service providers, service requesters, and service registry.

  • Deployment Infrastructure, that is the service bundles which contain implementation classes, resources, bundle metadata, and manifest file.

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

Discover about the concepts used in JDeveloper extension development.

Only those extensions load during the JDeveloper startup that are required for the user to enhance the startup performance and overall memory usage. Some extensions related terms and concepts are described below:

  • JDeveloper users choose a role in which to work, and the role determines which JDeveloper extensions are loaded because roles list the set of possible extensions for that role. For example, the JDeveloper default role lists all extensions in the Studio Edition.

  • Initialization is an operation that involves calling the extension initialization code Addin.initialize(). Extension initialization gives the extension an opportunity to initialize whatever it needs to function properly at the moment the end user is about to exercise that extension's functionality.

    The initialization list is a list of extensions previously initialized. These same extensions are initialized when the user reopens a project recording this list.

  • Trigger hooks are a set of declarative integration hooks that provide the mechanism to trigger extension initialization. They are defined in the <trigger-hooks> section of the extension manifest extension.xml, and they are processed when JDeveloper starts, even though your extension may not have been initialized.

    Any information the JDeveloper IDE needs about your extension at startup, such as the gallery items it contributes, or the Java libraries it defines, or the node recognizers it defines, must be provided in trigger hooks.

    By contrast, the <hooks> section of the extension manifest is processed later when your extension is initialized.

  • Registration is an operation that involves reading and caching the trigger hooks section of the extension manifest.

  • Lazy initialization is the term for extensions not being initialized until their trigger hook is activated.

  • Extension versioning is managed by OSGi. Two or more versions of the same extension can be loaded at the same time, and if an extension is activated all dependent extensions are also loaded. OSGi handles the situation of an extension depending on a certain version or range of versions.

  • Extensions are class loaded in their own classloader. The extension lists the set of packages that it exports to other extensions. The OSGi bundle manifest file defines the Java packages that are made available to other bundles. Access to the restricted classes is not possible, even using reflection, since OSGi protects them by means of the extension's Java classloader.

  • The OSGi service infrastructure dynamically manages service providers and requesters.

  • Extensions can have dependencies on other extensions. When an extension is loaded, any other extension marked as a dependency in the OSGi bundle manifest is also loaded. You may have already experienced this in JDeveloper, when you have to click Load Feature, for example, in the Application Properties, Project Properties, or Preferences dialog to start up a feature that you have not accessed before, and have to wait while the relevant extensions load.

  • JDeveloper extensions conform to the JSR 198 specification, which provides a standard extension API for IDEs. Seehttp://jcp.org/en/jsr/detail?id=198.

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 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 the Applications window, 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 Applications window 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

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 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 since this 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 Understanding Large Extensions.

1.4 Migrating Extensions from Previous Releases

Extensions developed for 11g and earlier versions of JDeveloper have to be updated to run in in JDeveloper 12c.

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 How 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:

  • The Addin.initialize method is no longer called at IDE startup. You must initialize your extension using a trigger hook.Trigger hooks are defined in the extension manifest extension.xml, and you can use one of the trigger hooks types defined by the JDeveloper IDE, or create a custom trigger hook. For more information, see Defining and Using Trigger Hooks.

  • Almost all <hooks> properties in the extension manifest extension.xml should now be placed in <trigger hooks>.

  • In earlier versions of JDeveloper, role files were exclusionary, meaning that by default all extensions were loaded and the role file told JDeveloper what not to load. Now role files are inclusive; only extensions listed in a role are able to be loaded when their trigger hook is activated.

  • All extensions have separate classloaders. As a result, code that calls package-protected methods from classes in the same package but different extensions will not work.

  • If your extension has custom integration points, these must be changed to handle on-demand extension initialization. For more information, see How Lazy Initialization Works.

  • Code that uses reflection to instantiate classes in an extension that it does not have explicit dependencies on will not work.

There are a number of use cases in 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.5 Getting Started With Extension Development

Begin developing an extension by creating an application.

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

1.5.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. See "About Working with Applications and Projects" in Developing Applications with 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 Extension Application. The Create Extension 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 Next. The project, which is configured for extension development, has a default name of Extension. If necessary, change the project name, then click Next.
  5. On the Configure Java Settings page you can set the default package, the Java source path and the output directory. Make the changes you want, then click Next.
  6. On the Configure Extension Settings page you can set options for the extension.

The extension project is created in the Applications window, and contains the elements shown in Figure 1-1.

Figure 1-1 Extension Project in the Applications Window

This image is described in the surrounding text

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.

If for some reason you do not want to create an Extension application directly, you can create a Custom application and select Extension Development as the project features on the Project page of the wizard.

1.5.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 application.


You can only develop an extension for more than one release of JDeveloper when the versions are both minor releases of the same major release. For example, JDeveloper version 11.1.2.nn can work with other 11.1.2.nn versions. If you are using 12.1.2.nn then you can only develop extensions that will work with other 12.1.2.nn releases.

The way that JDeveloper extensions are written changed in JDeveloper 11g release 11.1.2.nn. To develop extensions for earlier versions of JDeveloper, see the documentation in that version of JDeveloper.

To choose the JDeveloper version the extension is for:

  1. Create an extension application.
  2. On the Configure Extension Settings page, choose a different Target Platform. If necessary, click the Manage Extension Platforms icon and choose the platform in the Manage Extension Platforms dialog. For more help, press F1 or click Help in the dialog.

1.5.3 Next Steps

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

1.6 Working with the Extension Manifest

Learn about the extension manifest for JDeveloper extensions.

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

This image is described in the surrounding text

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 Understanding Dependencies.

The template code for extension.xml created by creating an extension project contains placeholders for the main elements, shown in the following example:

<extension id="extension" version="1.0.0" esdk-version="2.0" rsbundle-class="extension.Res"
  <trigger-hooks xmlns="http://xmlns.oracle.com/ide/extension">
    <!-- TODO Declare triggering functionality provided by extension: extension -->
    <!-- TODO Declare functionality provided by extension: extension -->

1.6.1 Editing the Extension Manifest in the Overview Editor

The overview editor for extension.xml updates the extension manifest extension.xml and the OSGI manifest manifest.mf declaratively.

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 Runtime tab updates manifest.mf and allows you to specify runtime values.

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 Understanding Dependencies.

Use the Hooks tab to specify how the extension binds to the IDE.

The Hook Handlers tab allows you to define trigger hooks in your extension that can be used as integration points by other extensions.

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

1.6.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 Developing Applications with Oracle JDeveloper.

1.7 Working with the OSGi Manifest

Learn how to use the OSGi manifest when creating JDeveloper extensions.

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.

Although you can edit the OSGi manifest in the source editor, it is preferable to edit it declaratively in the overview editor. For more information, see Editing the Extension Manifest in the Overview Editor.

When a new extension project is created, a default MANIFEST.MF is created, and the initial content is shown in the following example:

Bundle-ManifestVersion: 2.0
Bundle-Version: 1.0.0
Bundle-SymbolicName: extension
Bundle-ClassPath: .
Require-Bundle: oracle.ide

For detailed information about the content of the OSGi manifest, see http://www.osgi.org.

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

  • Require-Bundle: Classes from another OSGi bundle that are required by your extension are listed. Comes from the require-bundles elements in the extension manifest.

  • Export-Package: When you want to make Java packages in your extension available to other extensions, these packages are listed.

  • Bundle-ClassPath: If your extension needs to reference classes from a JAR which is not an OSGi bundle it is listed. Comes from <dependencies> elements in the extension manifest.

These values are used in the OSGi Bundle Profile dialog. For more information, see How to Create the Deployment Profile.

1.7.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

  • 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. 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 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. If necessary, open extension.xml in the overview editor by double-clicking on extension.xml under META-INF in the Applications window. Select the Dependencies tab.
  2. To specify that other extensions are dependent on this extension, use the Imported Packages section.

    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, use the Require Bundles section to specify one or more bundles that depend on this extension.

    The extensions you select as listed as <bundle> elements in the <require-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. 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 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.