## page was renamed from Cytoscape_3.0/Eclipse/PluginDevelopment = How to Build an OSGi-Based Cytoscape 3 Plugin on Eclipse = == Status == * Document rev. 0.9 released. Confirmed to work on Linux and Mac: KeiichiroOno * Document rev. 1.0 released. Confirmed to work on Windows, Linux and Mac: KeiichiroOno <> * Document rev. 1.1 draft. Added new Step 4 and several 'MLC' comments and questions that need answering: Michael Creech <> <> == Introduction == This tutorial is a step-by-step instruction for creating Cytoscape 3 plugin based on OSGi framework. By following this tutorial, you can create a new plugin for Cytoscape 3. == Background == In an OSGi system, '''''everything is a plugin'''. This means, Cytoscape 3 running on OSGi framework is a collection of plugins called '''''bundle''''' and developing a plugin for Cytoscape 3 is equivalent to developing OSGi bundles. '' '''''MLC:''' I'm finding the use of the term 'plugin' really confusing because there appears to be at least four different types of 'plugins'. There are the older (C2.6) Cytoscape plugins, Maven plugins, Eclipse plugins (that use OSGI framework?), and OSGi plugins. Several of these are being referenced in various ways in this document. How can we clearly differentiate each type of plugin?'' The main difference between Cytoscape 2.x plugin and 3.x plugin is that you '''''do not''''' have to implement CytoscapePlugin interface in Cytoscape 3. Instead, you need to build your plugin jar file with metadata for OSGi. However, this process will be handled by Eclipse and other tools and you do not have to create metadata manually. == Requirements == To understand each steps in this document, it is better to understand following before building your plugin: * Basic Java * How to build Java project on Eclipse * OSGi Bundle * Note: OSGi Bundle = regular jar file + metadata text file. * OSGi-Dependent API * !BundleActivator === Tools === The following tools should be installed on your machine before starting this tutorial: * [[http://www.eclipse.org/|Eclipse 3.3/3.4]] * [[http://maven.apache.org/|Maven]] 2.0.9 or later * [[http://www.ops4j.org/projects/pax/construct/|Pax-Construct 1.3]] * [[http://java.sun.com/javase/downloads/index_jdk5.jsp|Java SE 5/6]] ==== Eclipse Plugins ==== * [[http://m2eclipse.codehaus.org/|m2Eclipse]] - Maven integration for Eclipse * [[http://subclipse.tigris.org/|Subclipse]] - [[http://subversion.tigris.org/|Subversion]] client for Eclipse * [[http://springide.org/blog/|Spring IDE]] (Optional) == Goal of This Tutorial == There are lots of ways to organize your plugin project directory, but in this tutorial, for simplicity, we will use the following directory structure: * Plugin Project Root - The root directory of your plugin project. * Plugin Bundle Directory - This is the actual directory to store plugin code. * wrappers - Wrapping existing library files as OSGi bundles __if they are not available as OSGi bundles__ Other directories will be generated automatically. Your workspace will look like the following: . {{attachment:pluginProjectTree.png}} In the example above, ''samplePluginA'' is the name of plugin project and ''plugin1'' is the name of plugin bundle. '''''MLC:''' I'm very confused with this structure. Why is the name of the plugin project different then the bundle? Why wouldn't be something like '''samplePluginA''' and '''samplePluginABundle'''? Is it better to place both the bundle and the plugin under a common superdirectory or separate them? If everything was under a common superdirectory, then it would be clear that '''samplePluginA''' is related to '''plugin1'''. Is there ever a case were you would have multiple bundles under the same plugin project? I would like a more general discussion of how we should name and place our new plugin (or name and place the migration of an existing C2.6 plugin to C3.0). '' '''''MLC:''' The naming used in this example should be changed to be consistent with the rest of this document (e.g., c3plugin and sampleBundle). '' == Prerequisite == Since this project depends on Cytoscape 3 core, you need to know how to build and run Cytoscape 3 on Eclipse. Please read [[Cytoscape_3.0/Eclipse/CoreDevelopment|this tutorial]] first. == Procedure == === Part 1: Create New Plugin Project === 1. Start Eclipse. For simplicity, I recommend to use fresh and empty workspace without any other projects. 1. Select '''''Run > Run Configurations...''''' 1. Right click '''''Maven Build''''' and create new configuration 1. Press '''''Variables...''''' and select '''''workspace_loc''''' as the destination directory for the new plugin project. However, the location is up to you. You can select any directory. {{attachment:pluginProject1.png}} 1. Press '''''Select...''''' and use the tree browser to expand '''''pax''''' and then choose '''''create-project''''' as the goal. 1. Press '''''Add''''' and set '''''artifactId''''' and '''''groupId'''''. Usually, ''groupId'' is based on your organization's URL. This is because once you publish your plugin in the Maven repository, the string ''groupId+artifactId'' must be unique to locate your project {{attachment:pluginProject2.png}} '''''MLC:''' Wouldn't the groupId be in java package form, so that it would be 'org.cytoscape' versus 'cytoscape.org'? '' '''''MLC:''' You need to make sure '''artifactId''' is a different name than your existing Eclipse projects, othwerwise you will run into conficts later. This is more of an issue when migrating C2.6 plugins to C3. '' 1. Press '''''Apply''''' and '''''Run'''''. 1. At this point, there is no new project in your workspace. This is normal since the process above only creates Maven project, not an Eclipse project. 1. Open '''''File > Import''''' window and expand 'General' in the tree browser, then select '''''Maven Projects''''' {{attachment:pluginProject3.png}} 1. Choose the 'Root Directory:' where your project is located and select all the checkboxes for your project. {{attachment:pluginProject4.png}} '''''MLC:''' Sometimes, when I perform this on windows, all the checkboxes below the top-level pom.xml file are grayed out. '' 1. Click the '''''Finish''''' button. === Part 2: Create Plugin Bundle === Next, you need to create an actual OSGi bundle of your plugin. You can create multiple bundles for a plugin, but in this tutorial, your plugin consists of one bundle. 1. Select '''''Run > Run Configurations...''''' 1. Right click '''''Maven Build''''' and create new configuration 1. '''''Browse Workspace''''' and select your project root directory 1. Set the goal to '''''create-bundle''''' under the '''''pax''''' entry in the tree browser. 1. Add two parameters for the new plugin. '''''package''''' will be the root package name of this bundle, and '''''bundleName''''' will be the name of your new plugin. Also, add '''''junit''''' parameter to automatically generate test case template. The value should be the version of JUnit you want to use. {{attachment:pluginProject5.png}} '''''MLC:''' You need to make sure '''bundleName''' is a different name than any of your existing Eclipse projects, othwerwise you will run into conficts later. This is more of an issue when migrating C2.6 plugins to C3. '' 1. Press '''''Apply''' and '''''Run''''' '' 1. Next, you need to add OSGi project nature to your workspace. Select '''''Run > Run Configurations...''''' 1. Right click '''''Maven Build''''' and create new configuration 1. '''''Browse Workspace''''' and select your project root directory 1. Goal should be '''''pax:eclipse''''' {{attachment:pluginProject6.png}} 1. Press '''''Apply''' and '''''Run''''' '' 1. Import the generated bundle into your workspace. It is same as part 1. Now your workspace looks like the following: {{attachment:pluginProject7.png}} The ''samplebundle'' folder is the actual project you are going to write your plugin. '''''MLC:''' Why do we have to have two eclipse projects--an OSGi plugin project and a bundle plugin? With our Cytoscape 2.6 versions of plugins, we then have three different Ecplipse projects per plugin. It sure would be nice to just have one C3 project. '' '''''MLC:''' What is the purpose of the mysterious "adding OSGi project nature"? '' '''''MLC:''' Do the names generated for the various settings projects in Eclipse (e.g., compiled-bundle-settings, provision, shared-bundle-settings, wrapper-bundle-settings) present a problem when you have several plugins? For example, are these settings files updated for each plugin or just represent the last plugin C3 plugin you created, or something else? '' ==== OSGi Project Directory Structure ==== In the ''samplebundle'' directory, you may see some new files you are not familier with. * Source Code - In Maven projects, source code is managed in two directories. * ''src/main'' - Main source code directory you are going to write your own plugin code. * ''src/test'' - For unit/integration test cases * Resource Files - If you need to include some resource files (image icons, etc.) you can put them under ''src/resources''. * MANIFEST.MF - Metadata for OSGi bundle. The most important part is the section '''''Export-Package''' and '''''Import-Package''''' which describes what packages are exported/imported. '' * osgi.bnd - This is the setting file for [[http://felix.apache.org/site/maven-bundle-plugin-bnd.html|maven-bundle-plugin]]. Instead of editing ''MANIFEST-MF'' directly, we are going to use the plugin to generate manifest file (metadata for OSGi bundle). For now, I'm not going into the detail about how to edit this file. * pom.xml - Setting file for Maven. === Part 3: Add Cytoscape Application Dependency === To run your plugin with Cytoscape 3 core distribution, you need to add all of its bundles to plugin pom.xml file. '''''MLC:''' What other times does this have to be performed? For example, would you would have to do these steps, along with erasing the previous , whenever you update Cytoscape and deploy-pom.xml has changed? You'd have to also remember to do this for '''all''' your plugins.'' 1. Assume you have already checked out Cytoscape 3 and run it by '''''pax:provision''''' goal 1. Open '''''CYTOSCAPE3_ROOT/runner/deploy-pom.xml''''' where CYTOSCAPE3_ROOT is the root directory of Cytoscape 3 project 1. Copy entire '''''dependencies''''' section from the xml file 1. Open your plugin root pom.xml file and paste all the dependencies from the previous step. After this, your pom.xml file will look something like: {{attachment:pluginProject8.png}} '''''MLC:''' The above screenshot is showing a small, truncated part of the pom.xml file, which is confusing. A new screenshot should be taken that makes this clear by removing the partial shot of '' (start the shot with ''), adding '...' above and below in the main screenshot, and adding the tag to the screenshot.'' === Part 4: Adding Your Plugin to the Maven Repository === You now need to add your plugin to the Maven repository so it can be found and loaded when you run Cytoscape. To do this from Eclipse, you need to make another run configuration that installs the plugin: 1. Select '''''Run > Run Configurations...''''' 1. Right click '''''Maven Build''''' and create new configuration. 1. Pick an approriate name for the configuration (e.g., '''Add Plugin to Repository'''), pick your Base directory to be your plugin root(e.g., '''${workspace_loc:/c3plugin}'''), and enter '''install''' in the Goals: box. 1. Click the Apply and Run buttons. The Eclipse console output should specify that the build was successful. After the build, your plugin will be in the Maven repository and ready to run. '''''MLC:''' We need a screenshot of the configuration. I can't make a screenshot that matches the look and feel and OS of the other screenshots.'' === Part 5: Run Template Project with Cytoscape === 1. Create new Maven Run target. Base directory is your plugin root (see the screenshot below) {{attachment:pluginProject9.png}} '''''MLC:''' For the goal, is the user suppose to type 'pax:provision' or select the provision goal under pax using the tree browser? If the goal is selected, then the real goal would be '''org.ops4j:maven-pax-plugin:1.3:provision'''.'' 1. Apply and Run. You can see Cytoscape 3 and your new plugin are running together on the same OSGi framework. {{attachment:pluginProject10.png}} If you type ''services'', you can see example OSGi service which is defined in the template code is running. {{attachment:pluginProject11.png}} 1. Quit Cytoscape === Part 6: Edit Template Code === Now you are ready to write your own code. Let's add a very simple code to the template. 1. Open '''''samplebundle > src/main/java > org.cytoscape.sample.internal > ExampleActivator.java''''' 1. Edit the following method and save it {{{ #!java public void start(BundleContext bc) throws Exception { System.out.println("STARTING org.cytoscape.sample"); Dictionary props = new Properties(); // add specific service properties here... System.out.println("REGISTER org.cytoscape.sample.ExampleService"); // Register our example service implementation in the OSGi service // registry bc.registerService(ExampleService.class.getName(), new ExampleServiceImpl(), props); JOptionPane.showMessageDialog(null, "Hello Cytoscape 3!", "Plugin Initialized", JOptionPane.INFORMATION_MESSAGE); } }}} 1. Right-click the root dir of the project (in this example, it is ''c3plugin'') and execute '''''Run As > Maven install''''' === Part 7: Debug your Plugin === 1. Add a brakepoint to your plugin code. As an example, add it in the new line you have just added to the template {{attachment:pluginProject12.png}} 1. Create a new debug configuration. Select '''''Run > Debug Configurations''''' and create new OSGi configuration. 1. In the ''Bundles'' tab, uncheck all bundles. Then select '''''Felix 1.0.4 via PAX Runner''''' for Framework {{attachment:pluginProject13.png}} 1. In the ''Arguments'' tab, add following as VM arguments {{{ -Xbootclasspath/a:bundles/com.jgoodies.looks_2.1.2.jar:bundles/cytoscape-sun.jhall_1.0.0.jar }}} {{attachment:pluginProject14.png}} 1. In the ''PAX Cursor'' tab, press ''Add POM'' and select '''''deploy-pom.xml''' under '''''PLUGIN_PROJECT_ROOT/runner''''' directory where PLUGIN_PROJECT_ROOT is your plugin project's root directory. You need to select ''Any File'' to make deploy-pom.xml be displayed. '' 1. Set ''update'' to '''''yes''''' {{attachment:pluginProject15.png}} 1. '''''Apply''' and '''''Debug'''''. PAX Runner executes Cytoscape 3 and your plugin. It will stop at the break point. '' {{attachment:pluginProject16.png}} 1. Press ''resume'' button and continue. Eventually, you will see the following dialog on the Cytoscape Desktop: {{attachment:pluginProject17.png}} == Use Spring Dynamic Modules for Your Plugin == If you want to use OSGi service mechanism, using Spring Framework is a good alternative to use OSGi-dependent API directly. In this section, you will learn how to create Spring-Powered bundles for your plugins. === Install Spring IDE === There is an Eclipse plugin for editing Spring configuration files. You can use this for your Spring-OSGi Cytoscape plugin project. Note: although this program is called ''Spring IDE,'' it is not an independent application. It is just a regular Eclipse plugin. You can follow this instruction to install it: http://springide.org/project/wiki/SpringideInstall === Create Spring-Powered Bundle === There are only two differences between OSGi-dependent plugins and Spring-DM plugins: 1. Add one more parameter when you create bundle. When you create a plugin bundle, add '''''spring''''' as an extra parameter. Then PAX Construct automatically generates template bundle project ready for writing Spring-DM code. {{attachment:spring1.png}} {{attachment:spring12.png}} 1. Set PAX Cursor profile to '''''spring'''. All you have to do is just check the '''''spring''''' checkbox on the Pax Cursor tab. '' {{attachment:spring2.png}} That's it. While your plugin is running with PAX Cursor, type ''ps'' in the console. You can see Spring-DM infrastructure bundles are running with Cytoscape 3. . {{attachment:spring3.png}} More advanced tutorial including how to write Spring-DM setting files will be available soon.