A Beginners Guide To Building Extensions for Oracle JDeveloper

By Shay Shmeltzer, Oracle
July, 2007

Introduction

Let's say you just thought of a cool new feature that you would like to see added to Oracle JDeveloper. You could ask Oracle to implement it, and if we see enough demand for it, we might actually get it into the next version. But if you are looking for a quicker turnaround time for this feature, you might want to consider writing the extension on your own.

JDeveloper offers an extension SDK that you can use to add anything to JDeveloper, from a new menu options, a new wizard or even a complete new code editor.
But how do you go about doing this?
In this article we'll aim to cover the basic steps you might want to follow. We'll be using a sample extension project that adds a "go to file" option to JDeveloper.
You can download the JDeveloper project for the extension from here.

Note: This article doesn't cover the JDeveloper extension sdk architecture in deep details - the JDeveloper online help topic for the extension SDK has more information about this.

Setting Up

When  building extensions for JDeveloper you'll probably want to use either the Java or J2EE edition of JDeveloper. You'll mostly be doing straight Java coding and maybe a little Swing design. You'll also be running JDeveloper in debug mode launching a complete JDeveloper to test your extension. For these reasons, you'll want the lighter version of the tool to get better performance.

Once you have a JDeveloper installation set up,  download the extension SDK (ESDK) for JDeveloper. The ESDK can be downloaded as an extension to JDeveloper through the help->check for update menu.
The Extension SDK includes the jars you need in order to use the extension API for JDeveloper, a new online help section about building extensions, and a set of code samples.

After you download the ESDK it will offer to install the samples - go ahead and install them - you'll get a  workspace with projects for each extension sample.
If you actually want to see a specific extension in action you can deploy it to the [jdev-root]\jdev\extensions directory and restart JDeveloper.

Tip: To open the workspace in a later point of time use the help->Open Extension Samples.

OK, we are done with the basic setup, next let's look at getting started with coding and extension.

Developing an Extension

When you first start developing with a new technology, many of the programs you build are created by coping code from samples and then changing it to match your needed functionality. This is probably the way to go with a JDeveloper extension as well. The ESDK samples can provide you with your base code.

I would suggest that you first decide what type of UI your extension needs. And then start by copying one of the ESDK samples. For example:

  • If you need to just add a menu option - copy FirstSample
  • If you need a dialog that will accept some input - copy DialogBox
  • If you need a wizard that will accept input - copy ClassGeneratorWizard

etc...

Just look at the description of the samples and pick the one that is right for you.

Tip: Several of the extensions developed by the community for JDeveloper are open-sourced, this mean that you can look at their code as well to get some programming tips.

In our project we want to let the user enter the name of the file in a dialog and then navigate to that file and open it in the editor. So we are going to use the DialogBox sample as the basis for our extension. Here is the full code for our extension - let's look at the specific areas we changed.

Usually you'll start by modifying all the strings to match the text you want for things like menu options etc. Then you'll get into modifying the actual extension code. For example adding a couple of additional items to your dialog layout. And of course you also want to hook-up your specific business logic to be executed when the extension is invoked.

In our sample we changed the name of the action in the following line

                               
                                 
48   public  static  final  int  GO_TO_FILE_CMD_ID  =  Ide.findOrCreateCmdID("GO_TO_FILE_CMD");
                              
                               

                            

We then defined the menu option in the initialize method for the extension - this method is executed when JDeveloper starts.

                               
                                 
108   public  void  initialize()  {
                              
                              


                               
                                 
109   
                                
// Create the Context Menu Item and add it to the Navigator Menu
                              
                              


                               
                                 
110   
                                
Controller  
                                
ctrlr1  
                                
=  
                                
this
                                
;
                              
                              


                               
                                 
111   
                                
JMenuItem  
                                
mi  
                                
=
                              
                              


                               
                                 
112   
                                
doCreateMenuItem
                                
(
                                
ctrlr1
                                
,  
                                
"Go To File ..."
                                
,  
                                
new  
                                
Integer
                                
(
                                
'O'
                                
))
                                
;
                              
                              


                               
                                 
113   
                                
JMenu  
                                
jmenu  
                                
=  
                                
Menubar
                                
.
                                
getJMenu
                                
(
                                
"Search"
                                
)
                                
;
                              
                              


                               
                                 
114   
                                
jmenu
                                
.
                                
add
                                
(
                                
mi
                                
)
                                
;
                              
                            

We then changed the dialog to show a drop down list - this section is in the handleEvent method of our extension - this method is called when the menu option is invoked.

                               
                                 
61   
                                
JComboBox  
                                
cb  
                                
=  
                                
new  
                                
JComboBox
                                
(
                                
new  
                                
Vector
                                
(
                                
projectFiles
                                
))
                                
;
                              
                              


                               
                                 
62   
                                
JEWTDialog  
                                
dlg  
                                
=
                              
                              


                               
                                 
63   
                                
OnePageWizardDialogFactory
                                
.
                                
createJEWTDialog
                                
(
                                
cb
                                
,  
                                
null
                                
,
                              
                              


                               
                                 
64   
                                
"Enter File Name"
                                
)
                                
;
                              
                              


                               
                                 
65   
                                
dlg
                                
.
                                
setDefaultButton
                                
(
                                
JEWTDialog
                                
.
                                
BUTTON_OK
                                
)
                                
;
                              
                              


                               
                                 
66   
                                
dlg
                                
.
                                
setOKButtonEnabled
                                
(
                                
true
                                
)
                                
;
                              
                            

In order to populate the list we needed to get a list of the files in our project's directory  and sub directories.
We wrote a specific method -populateFileListForProject - to achieve this - and passed to it the base directory for our current active project.

                               
                                 
55   
                                
projectFiles  
                                
=
                              
                              


                               
                                 
56   
                                
populateFileListForProject
                                
(
                                
Ide
                                
.
                                
getActiveProject
                                
()
                                
.
                                
getBaseDirectory
                                
())
                                
;
                              
                            

The only additional change we made to the ESDK code sample is to add a keyboard accelerator by creating an accelerators.xml file and registering it as part of the initialization method with the lines:

                               
                                 
116   
                                
//This section adds the file that specify the keyboard accelerator
                              
                              


                               
                                 
117   
                                
KeyStrokeContextRegistry  
                                
r  
                                
=  
                                
Ide
                                
.
                                
getKeyStrokeContextRegistry
                                
()
                                
;
                              
                              


                               
                                 
118   
                                
r
                                
.
                                
addAcceleratorDefinitionFile
                                
(
                                
FileBrowser
                                
.
                                
class
                                
.
                                
getClassLoader
                                
()
                                
,
                              
                              


                               
                                 
119   
                                
"META-INF/accelerators.xml"
                                
)
                                
;
                              
                            

Testing and Debugging Extensions

Now that you have a first cut of your code you'll want to test it - right?
How do you test an extension to JDeveloper? Simply by installing the extension and running JDeveloper.

In order for your extension to be installable you need to create an extension.xml file in a META-INF directory.
You can just copy the text for the file from one of the extension samples.
Then make sure to change the following:
id= should be the full path to your extension class
name and owner and description - any text that makes sense
addins should again have the full path to your extension class

<?xml version="1.0" encoding="windows-1252" ?>
<extension xmlns="http://jcp.org/jsr/198/extension-manifest"
           id="shay.org.ext.FileBrowser" version="1" esdk-version="1.0">
  <name>Go To File</name>
  <owner>Shay Shmeltzer</owner>
  <dependencies>
    <import>oracle.ide</import>
  </dependencies>
  <hooks>
    <jdeveloper-hook xmlns="http://xmlns.oracle.com/jdeveloper/1013/extension">
      <addins>
        <addin>shay.org.ext.FileBrowser</addin>
      </addins>
    </jdeveloper-hook>
    <feature-hook>
      <description>Adds a menu option that allows you to quickly open any file
                   in your project's directory (ctrl alt -).</description>
      <optional>true</optional>
    </feature-hook>
  </hooks>
</extension>   

To learn more about the extension.xml file and the other options you can specify in the file check out the [jdev-root]\jdev\doc\extension\ide-extension-packaging.html file in your JDeveloper installation directory.

In order to deploy the extension, create a new JAR deployment descriptor for your project - and specify that the JAR will get created in the [jdev-root]\jdev\extensions directory of your JDeveloper.
Also make sure that the JAR name will be your full class path in addition to the version number you specified in the extensions.xml file.
Then just deploy the deployment profile to create the JAR.

deployment profile


Next we'll use a little trick that will let you run and debug JDeveloper itself when your run your extension project.
Go into your project properties and edit your run/debug configuration set the default run target to be the file [jdev-root]\jdev\bin\jdev.conf. Now if you'll run your project a new instance of JDeveloper will start and if you placed the JAR file in the right location as described above your extension will be active.

run configuration

If something is not working correctly then just set a breakpoint in your extension code and instead of clicking the run button hit the debug button to debug JDeveloper itself.

That's it - have fun fine-tuning your extension to work exactly as expected.

Once you are done, it is time to distribute your extension.

Distributing Extensions

Starting with JDeveloper 10.1.3 extensions can be easily installed through the help->check for update menu in JDeveloper.

In order for your extension to be installable in this way you'll need to create a simple zip file that will contain your extension JAR as well as a META-INF directory with a bundle.xml file.
Here is the content you need to put in your bundle.xml file.

<update-bundle version="1.0"
               xmlns="http://xmlns.oracle.com/jdeveloper/updatebundle"
               xmlns:u="http://xmlns.oracle.com/jdeveloper/update">
  <!-- The id *MUST* match exactly the id in your extension.xml. -->
  <u:update id="shay.org.ext.FileBrowser">
    <!-- The name of your extension as you want it to appear under the check for update menu -->
    <u:name>Go To File</u:name>
    <!-- The version *MUST* match exactly the version in your extension.xml. -->
    <u:version>1</u:version>
    <u:author>Shay Shmeltzer</u:author>
    <u:author-url>http://blogs.oracle.com/shay/2007/07/10#a471</u:author-url>
    <u:description>Adds a menu option and keyboard short-cut (ctrl alt -) that
                   allows you to quickly navigate to and open any file in your
                   project's directory.</u:description>
  </u:update>
</update-bundle>

Once you have the zip - you can test an installation by going through the help->check for update and choosing to install from a local file - just point to the zip and you should be ok.

If you think other people might enjoy your extension you can host the zip file somewhere on the Web, and let us know on the  JDeveloper discussion forum.
We'll then add your extension to the partners/open source update center and people will be able to install your new extension directly from inside JDeveloper with one click.

An even better idea would be to have your extension hosted as an open source project (Google code, sourceforge etc) on one of the many open source code hosting sites. This way other people can help you enhance your extension and further develop it.

Additional Information

To learn more about developing JDeveloper extensions visit the following links:

 

false ,,,,,,,,,,,,,,,,