Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Plugin Directory Structure"

(New page: When you use Maven2 to develop a Hudson plugin, Maven takes care of most of the stuff explained here. A plugin is really just a jar file that follows a certain set of conventions, as desc...)
 
 
Line 2: Line 2:
  
 
A plugin is really just a jar file that follows a certain set of conventions, as described below:
 
A plugin is really just a jar file that follows a certain set of conventions, as described below:
 
+
<pre>
 
foo.hpi
 
foo.hpi
 
  +- META-INF
 
  +- META-INF
Line 10: Line 10:
 
  |  +- lib
 
  |  +- lib
 
  +- (static resources)
 
  +- (static resources)
 
+
</pre>
    A plugin needs to have an .hpi extension. The file name body ("foo" portion) of the file name is used as the "short name" of a plugin, and it uniquely distingusihes a plugin.
+
*A plugin needs to have an .hpi extension. The file name body ("foo" portion) of the file name is used as the "short name" of a plugin, and it uniquely distingusihes a plugin.
    As you can see, the structure is similar to a WAR file, but there's no web.xml.
+
*As you can see, the structure is similar to a WAR file, but there's no web.xml.
    MANIFEST.MF needs to contain a few additional entries. More on this later.
+
*<code>MANIFEST.MF</code> needs to contain a few additional entries. More on this later.
    WEB-INF/classes can have class files that constitute plugins, Jelly view files, and Jelly tag libraries based on tag files. Alternatively, some or all of them can be packaged into a jar and placed into WEB-INF/lib.
+
*<code>WEB-INF/classes</code> can have class files that constitute plugins, Jelly view files, and Jelly tag libraries based on tag files. Alternatively, some or all of them can be packaged into a jar and placed into WEB-INF/lib.
    WEB-INF/lib can have *.jar files, and those are loaded and made available to a plugin ClassLoader, along with the contents of WEB-INF/classes.
+
*<code>WEB-INF/lib</code> can have *.jar files, and those are loaded and made available to a plugin ClassLoader, along with the contents of WEB-INF/classes.
    Static resources, such as images, HTML files, CSS stylesheets, JavaScript files, etc, can be placed at the top of an .hpi file (just like a WAR file, again.)
+
*Static resources, such as images, HTML files, CSS stylesheets, JavaScript files, etc, can be placed at the top of an .hpi file (just like a WAR file, again.)
  
 
== Manifest ==
 
== Manifest ==
  
META-INF/MANIFEST.MF can have all the normal entries, but it needs to contain two more entries for Hudson in its main section.
+
<code>META-INF/MANIFEST.MF</code> can have all the normal entries, but it needs to contain two more entries for Hudson in its main section.
 
=== Plugin-Class ===
 
=== Plugin-Class ===
  
Line 45: Line 45:
  
 
The hpl file can be placed in $HUDSON_HOME/plugins just like hpi files. But hpl file just contains a single line of text that points to a manifest file, like this:../path/to/your/plugin/workspace/manifest-debug.mf The file pointed by this is a manifest file. It has the same custom attributes as defined above for META-INF/MANIFEST.MF, but it defines a few more custom attributes that allow a plugin developer to specify various pieces of a plugin in different locations in a file system.
 
The hpl file can be placed in $HUDSON_HOME/plugins just like hpi files. But hpl file just contains a single line of text that points to a manifest file, like this:../path/to/your/plugin/workspace/manifest-debug.mf The file pointed by this is a manifest file. It has the same custom attributes as defined above for META-INF/MANIFEST.MF, but it defines a few more custom attributes that allow a plugin developer to specify various pieces of a plugin in different locations in a file system.
 
+
<pre>
 
Plugin-Class: hudson.plugins.jwsdp_sqe.PluginImpl
 
Plugin-Class: hudson.plugins.jwsdp_sqe.PluginImpl
 
Class-Path: ./build/classes ./views ./lib/reporter.jar
 
Class-Path: ./build/classes ./views ./lib/reporter.jar
 
Long-Name: JWSDP SQE Test Result Plugin
 
Long-Name: JWSDP SQE Test Result Plugin
 
Resource-Path" ./resources
 
Resource-Path" ./resources
 +
</pre>
 +
For example, the above sample manifest-debug.mf states that the static resources of a plugin shall be loaded from the <code>./resources</code>, and class files from <code>./build/classes</code>, Jelly view files in <code>./views</code>, and a library jar file <code>reporter.jar</code> shall be made available to the plugin classloader. Absolute path names can be also used.
  
For example, the above sample manifest-debug.mf states that the static resources of a plugin shall be loaded from the ./resources, and class files from ./build/classes, Jelly view files in ./views, and a library jar file reporter.jar shall be made available to the plugin classloader. Absolute path names can be also used.
+
This mechanism allows a plugin developer to avoid assembly steps. Also, changes to static resources and Jelly views will be reflected instanteneously (provided that you set the system property <code>stapler.jelly.noCache</code> to true when you start the web container.
 
+
This mechanism allows a plugin developer to avoid assembly steps. Also, changes to static resources and Jelly views will be reflected instanteneously (provided that you set the system property stapler.jelly.noCache to true when you start the web container.
+

Latest revision as of 21:08, 16 July 2013

When you use Maven2 to develop a Hudson plugin, Maven takes care of most of the stuff explained here.

A plugin is really just a jar file that follows a certain set of conventions, as described below:

foo.hpi
 +- META-INF
 |   +- MANIFEST.MF
 +- WEB-INF
 |   +- classes
 |   +- lib
 +- (static resources)
  • A plugin needs to have an .hpi extension. The file name body ("foo" portion) of the file name is used as the "short name" of a plugin, and it uniquely distingusihes a plugin.
  • As you can see, the structure is similar to a WAR file, but there's no web.xml.
  • MANIFEST.MF needs to contain a few additional entries. More on this later.
  • WEB-INF/classes can have class files that constitute plugins, Jelly view files, and Jelly tag libraries based on tag files. Alternatively, some or all of them can be packaged into a jar and placed into WEB-INF/lib.
  • WEB-INF/lib can have *.jar files, and those are loaded and made available to a plugin ClassLoader, along with the contents of WEB-INF/classes.
  • Static resources, such as images, HTML files, CSS stylesheets, JavaScript files, etc, can be placed at the top of an .hpi file (just like a WAR file, again.)

Manifest

META-INF/MANIFEST.MF can have all the normal entries, but it needs to contain two more entries for Hudson in its main section.

Plugin-Class

This attribute must have the fully qualified class name of the class that derives from Plugin. Hudson instantiates this instance to activate a plugin, and everything starts from there. Consequently, a plugin must have one Plugin-derived class. This is the Hudson plugin version of the Main-Class attribute.

Long-Name

This optional attribute can have a human-readable one line description of the plugin. This is used as "the name" for users (whereas the short name is used as the name internally in Hudson.) When this attribute is not present, the short name is used as the long name.

Plugin-Dependencies

This optional attribute can have a list of comma-separated plugin short names/versions that are required for this plugin to run. The classes and libraries of those plugins are made visible to this plugin's classloader, so that your plugin can rely on them. This mechanism allows a plugin to define its own extensibility point, and have other plugins provide implementations.

Plugin-Dependencies: module-name:version,module2-name:version

Static Resources

Static resources inside an .hpi file will be made accessible at ${HUDSON_CONTEXT_PATH}/plugin/SHORTNAME/. For example, if you have abc/def.png in foo.hpi, and if Hudson is deployed on http://localhost/hudson/, then the URL http://localhost/hudson/plugin/foo/abc/def.png would display the PNG file.

Index.jelly for Your Plugin-derived Class

Your Plugin class (that you named in Plugin-Class manifest entry) should have index.jelly view file, which should render 1-2 paragraph worth of the detailed description of your plugin, perhaps with version numbers, link to the homepage, etc. This jelly script will be used in the plugin configuration page so that the user can learn more about a plugin.

Debug Plugin Layout: .hpl

The .hpi format is primarily meant to be a distribution format. Just like no one debugs the web application by creating a war and deploying it, Hudson provides another plugin layout called .hpl (for "Hudson plugin link"), which is targeted for plugin developers to improve productivity.

The hpl file can be placed in $HUDSON_HOME/plugins just like hpi files. But hpl file just contains a single line of text that points to a manifest file, like this:../path/to/your/plugin/workspace/manifest-debug.mf The file pointed by this is a manifest file. It has the same custom attributes as defined above for META-INF/MANIFEST.MF, but it defines a few more custom attributes that allow a plugin developer to specify various pieces of a plugin in different locations in a file system.

Plugin-Class: hudson.plugins.jwsdp_sqe.PluginImpl
Class-Path: ./build/classes ./views ./lib/reporter.jar
Long-Name: JWSDP SQE Test Result Plugin
Resource-Path" ./resources

For example, the above sample manifest-debug.mf states that the static resources of a plugin shall be loaded from the ./resources, and class files from ./build/classes, Jelly view files in ./views, and a library jar file reporter.jar shall be made available to the plugin classloader. Absolute path names can be also used.

This mechanism allows a plugin developer to avoid assembly steps. Also, changes to static resources and Jelly views will be reflected instanteneously (provided that you set the system property stapler.jelly.noCache to true when you start the web container.

Back to the top