<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TechJava&#187; TechJava &#8211; Articles tagged by plugin</title>
	<atom:link href="http://www.techjava.de/topics/tag/plugin/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.techjava.de</link>
	<description>Journal on Java Technology</description>
	<lastBuildDate>Thu, 17 Jun 2010 10:41:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Packaging Eclipse-based RCP for the use in enterprise context</title>
		<link>http://www.techjava.de/topics/2009/07/packaging-eclipse-based-rcp-for-the-use-in-enterprise-context/</link>
		<comments>http://www.techjava.de/topics/2009/07/packaging-eclipse-based-rcp-for-the-use-in-enterprise-context/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 20:00:33 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[eclipse]]></category>
		<category><![CDATA[enterprise systems]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[rcp]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[packaging]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[product]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=394</guid>
		<description><![CDATA[
Abstract
Using Eclipse-based rich-clients as stand-alone applications is discussed in many 
books and 
articles. In the context of enterprise systems, the software development adopted several paradigms to improve the quality of the overall architecture. This short article describes some issues in packaging the application for using it in the context of enterprise systems.
Architectural Assumptions
Designing enterprise architectures [...]]]></description>
			<content:encoded><![CDATA[<p><img style="margin: 5px; float: right" title="Packaging" src="http://www.techjava.de/wp-content/uploads/packaging.jpg" alt="Packaging" width="120" height="120" /></p>
<h2>Abstract</h2>
<p>Using Eclipse-based rich-clients as stand-alone applications is discussed in many 
<a  href="http://www.amazon.com/Eclipse-Rich-Client-Platform-Applications/dp/0321334612" onclick="javascript:pageTracker._trackPageview('/external/www.amazon.com/Eclipse-Rich-Client-Platform-Applications/dp/0321334612');" >books</a> and 
<a  href="http://www.eclipse.org/articles/Article-RCP-1/tutorial1.html" onclick="javascript:pageTracker._trackPageview('/external/www.eclipse.org/articles/Article-RCP-1/tutorial1.html');" >articles</a>. In the context of enterprise systems, the software development adopted several paradigms to improve the quality of the overall architecture. This short article describes some issues in packaging the application for using it in the context of enterprise systems.</p>
<h2>Architectural Assumptions</h2>
<p>Designing enterprise architectures is a standard discipline for IT-consulting companies or freelancers involved in software development. Maybe one of the main characteristics of enterprise architectures is the framework-driven approach of software creation. Thus, the software has to comply certain rules and standards adopted inside the enterprise. In order to simplify such constrained development process, it is common to use an in-house software framework, which enforces the  compliance of the enterprise-internal standards and acts as glue between different technologies adopted as parts of the enterprise architecture.</p>
<p>Using such frameworks has major implications for the software development in general, and especially for the rich client development. The design issues are summarized in the next section.</p>
<h2>Usaging an Enterprise Framework</h2>
<p>The major goal of the enterprise in-house framework is to simplify the process of software systems development and to enforce standardization among the software systems. This usually includes the following aspects:</p>
<ul>
<li>Domain-specific component framework</li>
<li>Methods for master data management</li>
<li>Infrastructure services: authentication, authorization, communication, security, printing, reporting</li>
<li>Application skeletons and launchers</li>
</ul>
<p>The more unification and standardization is included inside the framework, the easier it is for a software developer to concentrate on the particular business task and the easier is the maintenance of the software system.</p>
<p>From the previous list, the most interesting part related to RCP packaging and deployment is the existence of the application skeletons and launchers. So, when launching an application, the framework libraries are loaded and executed first and pass the control to the application-specific modules. The advantage of this approach is that infrastructure services can be loaded first, which can be developed and shared among different applications.<br />
<span id="more-394"></span></p>
<h2>The required plug-ins</h2>
<p>Following the general idea of RCP packaging (see rules provided in the 
<a  href="http://www.amazon.com/Eclipse-Rich-Client-Platform-Applications/dp/0321334612" onclick="javascript:pageTracker._trackPageview('/external/www.amazon.com/Eclipse-Rich-Client-Platform-Applications/dp/0321334612');" >RCP Book</a>) and assuming one target platform (in terms of one RCP product), <strong>one top-level plug-in and should be defined</strong>. In addition, we assume at least one <strong>in-house framework plug-in</strong> and at least <strong>one application-specific plug-in</strong>. Usually there will be more of each type, but it will not change the picture much. Important at this point is the fact, that the application-specific code depends on the in-house framework code. In order to simplify the identification of the plug-ins, an example project is introduced. Let’s assume the project is called <strong>FooBar</strong>. Then, the plug-ins are called:</p>
<ul>
<li><code>de.techjava.foobar</code>: This is the functional plug-in, which contains the application-specific code.</li>
<li><code>de.techjava.framework</code>: This is the framework plug-in, which contains framework component code.</li>
<li><code>de.techjava.foobar.product.standalone</code>: This is an application and product definition plug-in which contains the definition of the product and application-agnostic code for launching the application.</li>
</ul>
<h2>Managing plug-in dependencies</h2>
<p>A difficult issue for the RCP beginners is the management of dependencies between plug-ins. Especially, the transition from the development of a single plug-in to the configuration of features and products seem to be non-trivial. In order to solve this problem, there are simple rules to follow. You can violate these rules in sophisticated scenarios, but for the beginners it is a good idea to follow them.</p>
<ol>
<li><em>Create dependencies only if you need them</em>. Each plug-in should only list plug-ins (or even better packages) it really depends on. Make sure to check it with the “<strong>Find unused dependencies</strong>” action available on the right-click in the Dependencies Tab of the Plug-in Manifest Editor.</li>
<li><em>Use versioning information. </em>Plug-ins (or better bundles, or as 
<a  href="http://www.aniszczyk.org/" onclick="javascript:pageTracker._trackPageview('/external/www.aniszczyk.org/');" >Chris</a> call them Plundles) provide version information. And it is highly advisable to include them in the import statements of the plug-ins, which simplifies the migration later on…</li>
<li><em>Don’t forget anything</em>. Every Plug-in should appear in at least in one Plug-In section of the Feature definition. Every feature should be included by another feature, higher in the hierarchy.</li>
<li><em>Keep the hierarchy flat</em>. For simple scenarios, it is sufficient to have two levels of features (top-level feature, one per-product and the underlying features include their plug-ins).</li>
<li><em>Don’t re-export dependencies</em>. Every Feature for a group of plug-ins should also include plug-ins required by the members of the group. It does not hurt if a plug-in is included several times, but it does if it is not included at all. You can optimize here if you check which plug-ins are imported by the Eclipse RCP feature (which can be considered as stable), but it does not make assumptions about features developed by third parties.</li>
</ol>
<p>Following these rules it is simple to create features for the corresponding plug-ins. Several plug-ins which belong together and are handled as a fixed piece can be grouped into Features. Usaging Features is highly advisable, and sometimes simply required (e.G. by RCP in a Java Web Start target deployment strategy). So in addition to the previously mentioned plug-in projects, at least three feature projects are required:</p>
<ul>
<li><code>de.techjava.foobar.feature</code>: This is a functional feature, which includes the <code>de.techjava.foobar</code> plug-in and all plug-ins required by it, which do not appear in the Eclipse RCP feature</li>
<li><code>de.techjava.framework.feature</code>: This is a framework feature, which includes the <code>de.techjava.framework</code> plug-in and all plug-ins required by it, which do not appear in the Eclipse RCP feature</li>
<li><code>de.techjava.foobar.feature.standalone</code> This is the top level feature, which is used for the product configuration. <strong>It includes the two features above and the Eclipse RCP feature </strong>(and optional other features used, like e.G. org.eclipse.help). <strong>It also includes exactly one plug-in</strong>, which is not included anywhere else: <code>de.techjava.foobar.standalone.product</code></li>
</ul>
<h2>The product definition plug-in</h2>
<p>The definition of the product is spread among several files. First of all the plug-in.xml of the <code>de.techjava.foobar.standalone.product</code> plug-in makes uses of two extensions:</p>
<ul>
<li><code>org.eclipse.core.runtime.applications</code></li>
<li><code>org.eclipse.core.runtime.products</code></li>
</ul>
<p>The application extension point is used to point to the Java class implementing the interface <code>org.eclipse.equinox.app.IApplication</code>. Along with this implementation, other classes needed to start up the RCP (like Advisors, etc…) are placed into the source directory of the plug-in. The product extension point is used for the association of the application with a product id. The previously-defined top-level feature includes all required features and the product definition plug-in. Finally, the <code>.product</code> file is the place, where all things are bound together: product id, application id, launcher parameters, and the one top level feature: <code>de.techjava.foobar.feature.standalone</code>. Other customization of the RCP is possible from the <code>plugin-customization.ini</code>, which is placed together with the <code>.product</code> file into the plug-in root directory.</p>
<p><img class="alignnone size-full" style="margin:10px;" title="Product configuration" src="http://www.techjava.de/wp-content/uploads/product_feature_plugin1.png" alt="Product configuration" width="385" height="499" /><br />
As a result the following configuration should be achieved after the packaging is finished. The product references the product-id and the application, defined in the plugin.xml of the plug-in project it is contained in. The product configuration is feature-based and includes one top-level feature. The top-level feature includes all other features (functional, framework, Eclipse RCP, other optional) and the one plugin, in which the product file resides.</p>
<p>The simple example provided in this articles is available as sourcecode for download (
<a  href="http://www.techjava.de/download/examples/rcp-packaging.zip" onclick="javascript:pageTracker._trackPageview('/downloads/download/examples/rcp-packaging.zip');" >rcp-packaging.zip</a>).</p>
<h2>The framework hooks</h2>
<p>In the introduced scenario, the packaging is not specific to the in-house framework. It just includes the feature containing the framework plug-in. This approach works fine, if the framework is used in a white-box manner, which means that the framework provides ready-to-use components to be plugged-in to the application (like e.G. a component for the master data management). The other type of frameworks is the so-called black-box framework, which provides components that have to be configured and integrated into the application components. In this case, the framework components can not be plugged-in using some declarative extension points, but need to be called from the application code. In the latter case, the dependencies appear between the plug-in launching the application (<code>de.techjava.foobar.standalone.product</code>) and the framework plug-ins. This requires a modification in the previous setup and the violation of one of the rules posted above. The plug-in has to define the dependency to the framework plug-in, but the top-level feature does not include the required plug-in directly, but imports the whole framework feature.</p>
<p></p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px">Technorati-Tags: 
<a rel="tag"  href="http://technorati.com/tags/eclipse" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/eclipse');" >eclipse</a>,
<a rel="tag"  href="http://technorati.com/tags/java" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/java');" >java</a>,
<a rel="tag"  href="http://technorati.com/tags/rcp" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/rcp');" >rcp</a>,
<a rel="tag"  href="http://technorati.com/tags/packaging" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/packaging');" >packaging</a>,
<a rel="tag"  href="http://technorati.com/tags/plugin" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/plugin');" >plugin</a>,
<a rel="tag"  href="http://technorati.com/tags/feature" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/feature');" >feature</a>,
<a rel="tag"  href="http://technorati.com/tags/product" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/product');" >product</a>,
<a rel="tag"  href="http://technorati.com/tags/enterprise+systems" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/enterprise+systems');" >enterprise systems</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2009/07/packaging-eclipse-based-rcp-for-the-use-in-enterprise-context/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Eclipse Common Navigator Framework</title>
		<link>http://www.techjava.de/topics/2009/04/eclipse-common-navigator-framework/</link>
		<comments>http://www.techjava.de/topics/2009/04/eclipse-common-navigator-framework/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 01:13:02 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[eclipse]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[rcp]]></category>
		<category><![CDATA[cnf]]></category>
		<category><![CDATA[common navigator]]></category>
		<category><![CDATA[common navigator framework]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[resource]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=302</guid>
		<description><![CDATA[
Abstract
This article describes some efforts to use the Common Navigator Framework (CNF). In doing so it incorporates the information already covered in different articles, but also focuses on the specific use case of providing a view of something completely unrelated to the platform resources. So the aim is not to add some content to the [...]]]></description>
			<content:encoded><![CDATA[<p><img style="margin: 10px; float:right;" title="compas" src="http://www.techjava.de/wp-content/uploads/compas.jpg" alt="compas" width="240" height="160" /></p>
<h2>Abstract</h2>
<p>This article describes some efforts to use the Common Navigator Framework (CNF). In doing so it incorporates the information already covered in different articles, but also focuses on the specific use case of providing a view of something completely unrelated to the platform resources. So the aim is not to add some content to the &#8220;Project Explorer&#8221; which is an example of resource-oriented CNF usage, but to provide a view on a completely own data model.</p>
<h2>Introduction</h2>
<p><img style="margin: 10px; float:left;" title="Project Explorer" src="http://www.techjava.de/wp-content/uploads/pe_01.png" alt="Project Explorer" width="272" height="179" /><br />
A very common UI element to represent data is a tree view. In SWT this UI element is implemented using the <code>Tree</code> widget. Following the MVC design pattern in the <code>TreeViewer</code>, JFace simplifies the usage of the Tree widget by delegating the task of content adoption to the ContentProvider and the label production to the LabelProvider (and using Sorters and Filters for sorting and filtering). Still for a single representation one has to construct a viewer and configure it with a corresponding Label- and ContentProvider. Further code reduction can be achieved by the use of <code>WorkbenchContentProvider</code> and <code>WorkbenchLabelProvider</code> if the elements can be made adaptable (implement <code>IAdaptable</code> interface and making them first-class workbench citizens). This approach is helpful, if the elements has to be displayed in several different viewers (e.G. Table). Finally, <strong>the Common Navigator Framework (CNF)</strong> is a facility provided by the Eclipse Platform which allows the usage of multiple Label- and ContentProvider on the same view. The providers are activated and used dynamically and can be configured declarative or programmatically. The advantage of CNF approach is the ability to combine elements in one view which have different origins(e.G. contributed by different plugins). CNF is used in Eclipse IDE: e.G. &#8220;ProjectExplorer&#8221; and &#8220;CVS Synchrnoize&#8221; are both instances of the CNF.</p>
<p>The usage of the CNF in your own application for purposes of representation of resource-based (and usually file-based) content is discussed in 
<a  href="http://scribbledideas.blogspot.com/2006/07/pdf-versions-now-available.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/07/pdf-versions-now-available.html');" >articles of Micael Elder</a> in detail. The main idea is to instantiate the view, declare the default content and UI interface and make some additions where needed. This post has a different aim: we start from scratch and represent completely resource unrelated content. Before diving in the implementation details, some overview is provided.</p>
<h2>UI Overview</h2>
<p><img style="margin: 10px; float:right;" title="Project Explorer with default options" src="http://www.techjava.de/wp-content/uploads/pe_02.png" alt="Project Explorer with default options" width="380" height="215" /> There are many things which can be configured by the usage of CNF and it is beyond the scope of this post to cover all of them. Still there are several things to understand before the actual code can be written. The user interacts with a View which shows the data elements. Which elements are shown is configured using the navigation content extensions. Shown elements can be filtered with Filters and sorted using Sorters on behalf of the user. There are some predefined actions and their positions in the UI and corresponding extension points to contribute to. <img style="margin: 10px; float:right;" title="Project Explorer Pop-up" src="http://www.techjava.de/wp-content/uploads/pe_031.png" alt="Project Explorer Pop-up" width="293" height="174" />. The actions for <strong>Working sets</strong>, <strong>Customize View</strong>, <strong>Link with editor</strong> belong to this category. The user can also right-click on particular element in the tree and sees a popup-menu. This menu is configured based on the content element and can be (is) contributed by several plugins. The action contribution is also covered in the article series from 
<a  href="http://scribbledideas.blogspot.com/2006/07/pdf-versions-now-available.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/07/pdf-versions-now-available.html');" >Michael Elder</a>.<br />
<br />
<span id="more-302"></span></p>
<h2>Minimal non-resource based CNF viewer</h2>
<p>The following example provide a set of minimal steps required to create a non-resource based CNF viewer. Your plug-in requires at least a dependency to <code>org.eclipse.ui.navigator</code>, <code>org.eclipse.ui</code>. </p>
<h3>Data model</h3>
<p>Let us assume a simple data model that should be represented in the view. There are two kinds of elements: parents and children (see Composite design pattern). Both Child and Parent are POJOs:</p>
<pre class="brush: java;">
public class Child
{
    private String name;
    private Parent parent;

    public Child(String name)
    {
        super();
        this.name = name;
    }

    // getters and setter
...
}
</pre>
<p>Every child stores information about its parent, and every parent knows its children. In order to maintain the model in-sync the <code>setChildren()</code> method of the <code>Parent</code> class takes care of unsetting on all previous children and setting the parent on new children. This is just a sample code and there are different ways to implement this more elegantly (like e.G. holding the parent-child relation externally).</p>
<pre class="brush: java;">
public class Parent extends Child
{
    private Child[] children = new Child[0];
    private Object rootElement;

    public Parent(String name)
    {
        super(name);
    }

    public void setChildren(Child[] children)
    {
        if (children != null)
        {
            setChildrensParent(null, this.children);
        }
        this.children = children;
        setChildrensParent(this, this.children);
    }

    /**
     * Sets children's parent
     * @param parent parent to be set
     * @param children children to set the parent
     */
    private static void setChildrensParent(Parent parent, Child[] children)
    {
        for (int i = 0; i &lt; children.length; i++)
        {
            children[i].setParent(parent);
        }
    }

    // getter and setter
...
}
</pre>
<p>Please note, that nothing more is assumed about the parent and the child. It is a good idea to make such elements implement <code>IAdaptable</code>, which simplifies a lot of issues later, but this is another topic. You may have noticed the <code>rootElement</code> member of the Parent. Again, this is only used in order to keep the object tree structure as simple as possible and provide a hook to the root of the tree. The final tree structure contains one root object, several parent objects containing several child objects each.</p>
<pre class="brush: java;">
public class Root extends PlatformObject
{
}
</pre>
<h3>Declaring the viewer</h3>
<p>In order to contribute a view to RCP/IDE the <code>org.eclipse.ui.views</code> extension point is used:</p>
<pre class="brush: xml;">
   &lt;extension
         point=&quot;org.eclipse.ui.views&quot;&gt;
      &lt;view
            class=&quot;de.techjava.rcp.cnf.provider.CNFNavigator&quot;
            id=&quot;de.techjava.rcp.cnf.view&quot;
            name=&quot;Virtual CNF&quot;
            restorable=&quot;true&quot;&gt;
      &lt;/view&gt;
   &lt;/extension&gt;
</pre>
<p>The two important things here are the <code>class</code> attribute pointing to the class of the CNF Navigator and the <code>id</code> attribute that will be used later in order to identify the view. Instead of pointing to the <code>org.eclipse.ui.navigator.CommonNavigator</code><br />
the reference to <code>ParentChildNavigator</code> is provided which is a subclass of the <code>CommonNavigator</code>. The reason for that is, that CommonNavigator gets its initial input (during initialization) from the Workbench by calling <code>getSite().getPage().getInput()</code>. In the IDE scenario, the default page input is <code>IWorkspaceRoot</code>, in the RCP scenario it is <code>null</code> and can be configured in the <code>WorkbenchAdvisor</code>. Instead, another implementation of <code>getInitialInput()</code> can be provided, passing the dummy Root object, which indicates the root of the tree. </p>
<pre class="brush: java;">
public class CNFNavigator extends CommonNavigator
{
    protected IAdaptable getInitialInput()
    {
        return new Root();
    }
}
</pre>
<h3>Defining viewer content</h3>
<p>In order to see something in the freshly-defined viewer, the information about the content has to be provided. The extension point <code>org.eclipse.ui.navigator.navigatorContent</code> is defined for this purpose. The main element responsible for the content is called <code>navigatorContent</code> and contains the following information:</p>
<ul>
<li><code>id</code> &#8211; the id of the content, to be referenced in the viewer</li>
<li><code>name</code> &#8211; the name of the content, which is seen in the <strong>Customize View</strong> dialog using the content tab, which can be activated or deactivated there by the user.</li>
<li><code>contentProvider</code> &#8211; the contentProvider class responsible for providing content elements</li>
<li><code>labelProvider</code> &#8211; the labelProvider class responsible for rendering a content element in the view</li>
</ul>
<pre class="brush: xml;">
   &lt;extension
         point=&quot;org.eclipse.ui.navigator.navigatorContent&quot;&gt;
      &lt;navigatorContent
            activeByDefault=&quot;true&quot;
            contentProvider=&quot;de.techjava.rcp.cnf.provider.CNFContentProvider&quot;
            id=&quot;de.techjava.rcp.cnf.content.VirtualContent&quot;
            labelProvider=&quot;de.techjava.rcp.cnf.provider.CNFLabelProvider&quot;
            name=&quot;Virtual content&quot;
            priority=&quot;normal&quot;&gt;
         &lt;triggerPoints&gt;...&lt;/triggerPoints&gt;
         &lt;possibleChildren&gt;...&lt;/possibleChildren&gt;
      ...
      &lt;/navigatorContent&gt;
   &lt;/extension&gt;
</pre>
<p>In addition, nested elements <code>triggerPoints</code> and <code>possibleChildren</code> describe when the current content is activated. This means that a CNF Viewer can compose the content coming from multiple providers and needs to know what content to display. These will be covered in the following sections. </p>
<h3>How the platform uses the viewer</h3>
<p>Before diving into the code section, it is worth spending a small section on the topic, how the platform uses the CNF viewer. In general, if an element is selected in the viewer, the CNF consults <code>triggerPoints</code> of all <b>Navigation Content Extensions (NCEs)</b> provided and tries to match the element to the trigger point expression. If the expression matches, the NCE is activated by the platform and the corresponding <code>contentProvider</code> is responsible for delivering content. If the element is activated by other means than in the viewer (e.G. in the Editor), the platform consults <code>possibleChildren</code> list and tries to match the corresponding expression. For resource-based approaches, the NCE with id <code>org.eclipse.ui.navigator.resourceContent</code> is usually provided. This NCE is enabled / triggered on any element that is instance of <code>IResource</code>. By this means e.G. the Project Explorer in the IDE passes the workspace root to the <code>ResourceExtensionContentProvider</code> which is responsible for delivering the children of the workspace root &#8211; the projects. In a non-resource based approach, the NCE must be triggered by the initial input of the viewer, in this example by the <code>Root</code> object. If the selected element is a <code>Parent</code> node, the NCE should also be triggered. The following definition of the trigger point accomplishes this task:</p>
<pre class="brush: xml;">
         &lt;triggerPoints&gt;
            &lt;or&gt;
               &lt;instanceof value=&quot;de.techjava.rcp.cnf.data.Root&quot; /&gt;
               &lt;instanceof value=&quot;de.techjava.rcp.cnf.data.Parent&quot; /&gt;
            &lt;/or&gt;
         &lt;/triggerPoints&gt;
</pre>
<p>Since the children delivered by the content provider on <code>Root</code> as parent element are instances of <code>Parent</code> and on <code>Parent</code> as parent element are instances of <code>Child</code>, the <code>possibleChildren</code> code looks as follows:</p>
<pre class="brush: xml;">
         &lt;possibleChildren&gt;
            &lt;or&gt;
               &lt;instanceof value=&quot;de.techjava.rcp.cnf.data.Parent&quot; /&gt;
               &lt;instanceof value=&quot;de.techjava.rcp.cnf.data.Child&quot; /&gt;
            &lt;/or&gt;
         &lt;/possibleChildren&gt;
</pre>
<h3>Label and Content providers</h3>
<p>After the way how the navigation content is being activated is discussed, the Content and Label providers can be addressed. The label provider implementation is straight-forward. Its task is to produce a textual and graphical representation of every element. In addition, it implements the <code>IDescriptionProvider</code> interface to provide description in the status bar when an element is selected. Please note, that this section is not CNF-specific but is related to JFace ContentProvider and JFace LabelProvider, as usual for any Viewer. It is provided here only for completion and if the user is not familiar with it in detail.</p>
<pre class="brush: java;">
public class CNFLabelProvider extends LabelProvider implements ILabelProvider, IDescriptionProvider
{
    public String getText(Object element)
    {
        if (element instanceof Parent)
        {
            return ((Child)element).getName() + &quot; [ &quot; +((Parent)element).getChildren().length + &quot; ]&quot;;
        } else if (element instanceof Child)
        {
            return ((Child)element).getName();
        }
        return null;
    }

    public String getDescription(Object element)
    {
        String text = getText(element);
        return &quot;This is a description of &quot; + text;
    }

    public Image getImage(Object element)
    {
        if (element instanceof Parent)
        {
            return PlatformUI.getWorkbench().getSharedImages()
              .getImage(ISharedImages.IMG_OBJ_FOLDER);
        } else if (element instanceof Child)
        {
            return PlatformUI.getWorkbench().getSharedImages()
              .getImage(ISharedImages.IMG_OBJ_FILE);
        }
        return null;
    }
}
</pre>
<p>The methods above are self-describing. For any element the text and image is selected based on element type. For children, the name is shown, for parents the number of children is displayed, additionally. The platform built-in icons of folder and file are used for convenience. The methods for the Label/Content provider usually follow this pattern of a <code>instanceof</code> cascade. </p>
<p>The content provider is responsible for the following tasks:</p>
<ul>
<li>At requested of <code>Root</code> it should deliver the list of <code>Parent</code> elements</li>
<li>At requested of <code>Parent</code> it should deliver the list of its children (<code>Child</code> elements)</li>
<li>At requested of <code>Child</code> it should deliver an empty list</li>
</ul>
<p>Since no real data model is available, its creation is hooked to the first access (that is, of course, for demonstration purposes only)</p>
<pre class="brush: java;">
public class CNFContentProvider implements ITreeContentProvider
{

    private static final Object[] EMPTY_ARRAY = new Object[0];
    private Parent[] parents;

    public Object[] getChildren(Object parentElement)
    {
        if (parentElement instanceof Root)
        {
            if (parents == null)
            {
                initializeParents(parentElement);
            }
            return parents;
        } else if (parentElement instanceof Parent)
        {
            return ((Parent) parentElement).getChildren();
        } else if (parentElement instanceof Child)
        {
            return EMPTY_ARRAY;
        } else
        {
            return EMPTY_ARRAY;
        }
    }

    public Object getParent(Object element)
    {
        if (element instanceof Child)
        {
            return ((Child) element).getParent();
        } else if (element instanceof Parent)
        {
            return ((Parent) element).getRoot();
        }
        return null;
    }

    public boolean hasChildren(Object element)
    {
        return (element instanceof Root || element instanceof Parent);
    }

    public Object[] getElements(Object inputElement)
    {
        return getChildren(inputElement);
    }

    public void dispose()
    {
        this.parents = null;
    }

    public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
    { /* ... */
    }
    ...
}
</pre>
<p>The class has three important methods: <code>getChildren(Object)</code>, <code>getParent(Object)</code> and <code>hasChildren(Object)</code>. The <code>getChildren(Object)</code> is responsible for delivering children elements to a given parent element. The <code>getParent()</code> delivers a parent for a given child element (e.G. when the child is selected using the editor and the viewer is requested to show the element in it). The <code>hasChildren(Object)</code> is a way of providing a more efficient implementation than <code>(getChildren(element).length == 0)</code>. The <code>getElements(Object)</code> method is usually delegated to <code>getChildren(Object)</code>. The difference between these methods is that <code>getElements(Object)</code> is called to obtain the tree viewer&#8217;s root elements, whereas <code>getChildren(Object)</code> is used to obtain the children of a given parent element in the tree (including a root). Since there is only one root (the not shown <code>IWorkspaceRoot</code>), it is OK to delegate. Finally, the <code>parents</code> member variable needs to be initialized on the first access, which can be done using the following code:</p>
<pre class="brush: java;">
    /**
     * Init code for empty model
     */
    private void initializeParents(Object parentElement)
    {
        this.parents = new Parent[3];
        for (int i = 0; i &lt; this.parents.length; i++)
        {
            this.parents[i] = new Parent(&quot;Parent &quot; + i);
            this.parents[i].setRoot(parentElement);
            Child[] children = new Child[3];
            for (int j = 0; j &lt; children.length; j++)
            {
                children[j] = new Child(&quot;Child &quot; + i + j);
            }
            this.parents[i].setChildren(children);
        }
    }
</pre>
<h3>Binding the content to the viewer</h3>
<p>The last remaining piece in the puzzle is to bind the content defined in the navigation content extension to the view defined in the view extension. The extension point <code>org.eclipse.ui.navigator.viewer</code> is responsible for that. It consists of several parts: the <code>viewer</code> element, that references the <code>id</code> of the view and the <code>viewerContentBinding</code> element that one one hand specifies the view to bind the content to and on the other hand provides a reference to the content definition id.</p>
<pre class="brush: xml;">
   &lt;extension
         point=&quot;org.eclipse.ui.navigator.viewer&quot;&gt;
      &lt;viewer
            viewerId=&quot;de.techjava.rcp.cnf.view&quot;&gt;
      &lt;/viewer&gt;
      &lt;viewerContentBinding
            viewerId=&quot;de.techjava.rcp.cnf.view&quot;&gt;
         &lt;includes&gt;
            &lt;contentExtension
                  isRoot=&quot;false&quot;
                  pattern=&quot;de.techjava.rcp.cnf.content.VirtualContent&quot;&gt;
            &lt;/contentExtension&gt;
         &lt;/includes&gt;
      &lt;/viewerContentBinding&gt;
   &lt;/extension&gt;
</pre>
<p>Please note, that the content id is provided in the <code>pattern</code> attribute. Instead of pointing to particular content id, the regex can be used (e.G. <code>de.techjava.rcp.cnf.content.*</code>). That&#8217;s it, look at the result.<br />
<img style="margin: 10px;" title="RCP virtual CNF" src="http://www.techjava.de/wp-content/uploads/rcp_cnf.png" alt="RCP virtual CNF" width="402" height="302" /><br />
Under <strong>&#8220;Custimize View&#8221;</strong> the content tab allows to show the defined &#8220;virtual content&#8221;. Since no filters are defined, the filter section is empty.<br />
<img style="margin: 10px;" title="RCP virtual CNF content selection" src="http://www.techjava.de/wp-content/uploads/rcp_cnf_content.png" alt="RCP virtual CNF content selection" width="406" height="416" /> </p>
<h2>Conclusion</h2>
<p>To my opinion, for almost every application using a tree/list view to represent entities the CNF should serve as a basis for the implementation. Thus, CNF documentation should be improved and get to the level &#8220;for beginners&#8221; rather than &#8220;for experts&#8221;. In this post, I have tried to provide an introduction for non-expert RCP/PDE developers. I&#8217;m interested in your comments.</p>
<h2>Further directions</h2>
<p>Currently, neither filters, sorters nor actions or pop-up menu are defined for the viewer. This can be a subject of the follow-up post, if requested, but is partly covered in the 
<a  href="http://scribbledideas.blogspot.com/2006/07/pdf-versions-now-available.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/07/pdf-versions-now-available.html');" >articles of Michael Edler.</a> Especially, the application of the new command framework has to be described.</p>
<h2>Resources</h2>
<h3>Eclipse</h3>
<ul>
<li>
<a  href="http://wiki.eclipse.org/index.php/Common_Navigator_Framework" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/index.php/Common_Navigator_Framework');" >CNF EclipseWiki page</a></li>
<li>
<a  href="http://dev.eclipse.org/blogs/francis/" onclick="javascript:pageTracker._trackPageview('/external/dev.eclipse.org/blogs/francis/');" >Common Navigator and Other Things by Francis Upton</a></li>
</ul>
<h3>Digital Paper Napkin by Michael D. Elder</h3>
<p>A basic set of introduction articles written in 2006. The articles introduce contribution to the resource-based CNF viewer displaying the content of the property files. A good overview to get into the subject. The blog seems to be dead, according to many spam comments.</p>
<ul>
<li>
<a  href="http://scribbledideas.blogspot.com/2006/05/building-common-navigator-based-viewer.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/05/building-common-navigator-based-viewer.html');" >Part 1 &#8211; Defining the Viewer</a></li>
<li>
<a  href="http://scribbledideas.blogspot.com/2006/05/building-common-navigator-based-viewer_22.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/05/building-common-navigator-based-viewer_22.html');" >Part 2 &#8211; Adding Content</a></li>
<li>
<a  href="http://scribbledideas.blogspot.com/2006/06/building-common-navigator-based-viewer.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/06/building-common-navigator-based-viewer.html');" >Part 3 &#8211; Configuring Menus</a></li>
<li>
<a  href="http://scribbledideas.blogspot.com/2006/06/building-common-navigator-based-viewer_18.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/06/building-common-navigator-based-viewer_18.html');" >Part 4 &#8211; Object Contribution</a></li>
<li>
<a  href="http://scribbledideas.blogspot.com/2006/06/building-common-navigator-_115067357450703178.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/06/building-common-navigator-_115067357450703178.html');" >Part 5 &#8211; Action Providers</a></li>
<li>
<a  href="http://scribbledideas.blogspot.com/2006/06/what-does-common-navigator-framework.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/06/what-does-common-navigator-framework.html');" >High Level Requirement on CNF</a></li>
<li>
<a  href="http://scribbledideas.blogspot.com/2006/05/where-do-we-go-from-here.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/05/where-do-we-go-from-here.html');" >Further directions</a></li>
<li>
<a  href="http://scribbledideas.blogspot.com/2006/07/pdf-versions-now-available.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/07/pdf-versions-now-available.html');" >PDF Versions</a></li>
<li>
<a  href="http://scribbledideas.blogspot.com/2006/07/label-decorators-in-common-navigator.html" onclick="javascript:pageTracker._trackPageview('/external/scribbledideas.blogspot.com/2006/07/label-decorators-in-common-navigator.html');" >Label decorators</a></li>
</ul>
<h3>Eclipse from the bottom up by Michael Valenta</h3>
<p>A good hint is to look on the implementation of the 
<a  href="http://eclipselowdown.blogspot.com/2006/05/common-navigator-and-synchronize-view.html" onclick="javascript:pageTracker._trackPageview('/external/eclipselowdown.blogspot.com/2006/05/common-navigator-and-synchronize-view.html');" >CVS Synchronize View</a>. Pretty old content, but still valid.</p>
<h3>vAAni by Aashish Patil</h3>
<p>Weakly formatted article, providing some hints on how to implement a not &#8220;resource only&#8221;-based CNF viewer. Still, the information from here helped me to create a complete 
<a  href="http://aashishpatil.blogspot.com/2006/07/displaying-non-resource-content-using.html" onclick="javascript:pageTracker._trackPageview('/external/aashishpatil.blogspot.com/2006/07/displaying-non-resource-content-using.html');" >non-resource based CNF viewer described here.</a></p>
<h3>Other</h3>
<p>Thanks to 
<a  href="http://dev.eclipse.org/blogs/francis/" onclick="javascript:pageTracker._trackPageview('/external/dev.eclipse.org/blogs/francis/');" >Francis Upton</a>, who reviewed the post and corrected some mistakes and misconceptions.</p>
<p>Special thanks to 
<a  href="http://bairdphotos.com/" onclick="javascript:pageTracker._trackPageview('/external/bairdphotos.com/');" >Michael &#8220;Mike&#8221; L. Baird</a> for the beautiful 
<a  href="http://www.flickr.com/photos/mikebaird/3009401040/" onclick="javascript:pageTracker._trackPageview('/external/www.flickr.com/photos/mikebaird/3009401040/');" >picture of the compass</a>. I found the picture on Google Image Search and became a big fan of his pictures (some of you know about 
<a  href="http://www.flickr.com/photos/sza/" onclick="javascript:pageTracker._trackPageview('/external/www.flickr.com/photos/sza/');" >my photo passion</a>). It is funny that from all places in the world, the picture is shot in Morro Bay, about 200 Miles away from where I&#8217;m located now. It is also funny that Mike is a computer science guy, even if retired&#8230;<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2009/04/eclipse-common-navigator-framework/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>RCP with multiple application windows</title>
		<link>http://www.techjava.de/topics/2009/01/rcp-with-multiple-application-windows/</link>
		<comments>http://www.techjava.de/topics/2009/01/rcp-with-multiple-application-windows/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 21:25:37 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[eclipse]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[rcp]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=228</guid>
		<description><![CDATA[

Eclipse RCP by default promotes the usage of a single application window with multiple views and editors inside. This default can be changed to multi-windowed application. The platform API offers several methods to operate with multiple application windows:

package org.eclipse.ui;
...
public interface IWorkbench ...
{
/**
* Retrieves the number of opened windows
*/
public int getWorkbenchWindowCount();
/**
* Retrieves the array of opened [...]]]></description>
			<content:encoded><![CDATA[<p>
<a  href="http://www.flickr.com/photos/33910833@N03/3195292012/" target="_blank" onclick="javascript:pageTracker._trackPageview('/external/www.flickr.com/photos/33910833@N03/3195292012/');" ><img style="margin: 10px; border: 0px; float: right;" src="http://farm4.static.flickr.com/3267/3195292012_4b4405c777_m.jpg" border="0" alt="" width="240" height="150" /></a><br />
Eclipse RCP by default promotes the usage of a single application window with multiple views and editors inside. This default can be changed to multi-windowed application. The platform API offers several methods to operate with multiple application windows:</p>
<pre class="brush: java;">
package org.eclipse.ui;
...
public interface IWorkbench ...
{
/**
* Retrieves the number of opened windows
*/
public int getWorkbenchWindowCount();
/**
* Retrieves the array of opened windows
*/
public IWorkbenchWindow[] getWorkbenchWindows();
/**
* Openes a new window with given perspective
*/
public IWorkbenchWindow openWorkbenchWindow(String perspectiveId,
IAdaptable input) throws WorkbenchException;
/**
* Performs a perspective switch in a given window
*/
public IWorkbenchPage showPerspective(String perspectiveId,
IWorkbenchWindow window, IAdaptable input)
throws WorkbenchException;
...

}</pre>
<p>Using this API, opening of new windows seems simple. For example one could define a perspective, that is always opens in a new window.</p>
<p>Closing windows is generally performed by calling <code>close</code> method on the <code>IWorkbenchWindow</code> instance.</p>
<pre class="brush: java;">
package org.eclipse.ui;
...
public interface IWorkbenchWindow ...
{
  /**
   * Closes the window
   */
  public boolean close();
}
</pre>
<p>Unfortunaly, there is no elegant way to find out which window are you in. A workaround which uses Eclipse internal API works fine for <code>WorkbenchWindow</code>, which is a standard platform implementation of the <code>IWorkbenchWindow</code> interface.</p>
<pre class="brush: java;">
/**
 * Determines if the window is a root window
 * @param window a window to be checked
 * @return true, if the window is considered to be a root window
 */
public static int getWindowId(IWorkbenchWindow window)
{
// HACK: note this could change in future
  if (window != null &amp;&amp; window instanceof WorkbenchWindow))
  {
    return ((WorkbenchWindow)window).getNumber();
  }
  return -1;
}
</pre>
<p>The initial application window gets the id 1. The lookup in the implementation reveals that the internal method finds the smalles unused positive number and assigns it to the newly opened window. If you do not want to rely on this algorithm, just hash the newly created windows by they ids.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2009/01/rcp-with-multiple-application-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The PluginLoader &#8211; Applying Java Class loading Concepts</title>
		<link>http://www.techjava.de/topics/2008/02/plugin-class-loader/</link>
		<comments>http://www.techjava.de/topics/2008/02/plugin-class-loader/#comments</comments>
		<pubDate>Mon, 25 Feb 2008 08:29:16 +0000</pubDate>
		<dc:creator>joker</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[class loader]]></category>
		<category><![CDATA[class loading]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[JAR]]></category>
		<category><![CDATA[JVM]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://www.techjava.de/topics/2008/02/plugin-class-loader/</guid>
		<description><![CDATA[Introduction
Many frameworks support plugins for increasing flexibility. They need to be loaded during runtime making it possible to change the supported features used in application without recompiling the framework and application themselves. Loading a plug-in means loading java classes, which is done by a class loader. We want to load the plug-ins from jar files, [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>Many frameworks support plugins for increasing flexibility. They need to be loaded during runtime making it possible to change the supported features used in application without recompiling the framework and application themselves. Loading a plug-in means loading java classes, which is done by a class loader. We want to load the plug-ins from jar files, without providing a name for every JAR. Unfortunately, the java standard API does not contain 
<a  href="http://www.techjava.de/topics/tag/class-loading/">a class loader</a> for loading classes from a list of jar files in a directory. We need to provide it ourselves. In addition, the standard class loading mechanism is designed with following idea in mind: in runtime the application accesses the known classname, that is searched for in class path and loaded if found. In our case, we want to force the framework load it extensions, without setting up the class path before applications starts, which is a little different use case.</p>
<h3>Simple JAR class loader</h3>
<p>The first step is loading classes from jar files. For this purpose we create a class named <strong>JarFileClassLoader</strong> which should be able to load a class from a jar file. It inherits from <strong>ClassLoader</strong>, the Java default implementation for a class loader. Loading a class from a jar file means scanning each jar file entries, decide if it is a class then load it. Because we want to be flexible about the criterion we use to select our classes, we introduce an interface <strong>ICriterion</strong>, which decides for a given class if the criterion is fulfilled or not. Using this, the JarFileClassLoader can now scan a single jar file and load every class fulfilling the injected criterion. Loading a class means scanning the caches of the parent class loaders, calling the <strong>loadClass(String)</strong> method of the parents if not found and scanning the jar file afterwards if the class was still not found. This beahviour is described in a previous 
<a  href="http://www.techjava.de/topics/tag/class-loading/">post</a>, introducing the basics of Java Class Loading. </p>
<p>JarFileClassLoader is capable of loading a class if it does not reference other classes. These references have to be resolved during class loading time. Let consider the example of classes A and B where A references B. If A is loaded by a class loader CL, CL is asked for loading B also. This is done by calling the <strong>loadClass(String)</strong> method of CL. If B is contained in the jar file CL loads classes from, CL will find it and return it to the JVM. If B is not contained in CL’s jar file, CL’s parents are asked to load it. Thus the class will be loaded if it is contained in the classpath where one of the java class loaders will find it. If the class is contained in another jar file in the list, but not in the class path it will not be found and the loading will end with a <strong>ClassNotFoundException</strong>.<br />
<img src="http://www.techjava.de/wp-content/uploads/PluginClassLoader/pluginclassloader.png" alt="Plugin Class Loader" style="float:right; margin:5px" /></p>
<h3>Plugin class loader</h3>
<p>To tackle this problem we introduce another class, the <strong>PluginLoader</strong>. It contains a collection of <strong>JarFileClassLoaders</strong> and inherits from ClassLoader, thus is a ClassLoader itself. The <strong>PluginLoader</strong> acts as a parent for all <strong>JarFileClassLoaders</strong> and is therefore asked every time a class has to be loaded. It will then iterate over all <strong>JarFileClassLoaders</strong> calling the <strong>loadClass(String)</strong> method on all of them to find the class it looks for. This way, classes contained in sibling class loaders are found also without violating the rule that a class loader can only see classes of itself or its parents. </p>
<h3>Putting everything together</h3>
<p>Now the structure of our plug-in loader component becomes clear. What we additionally need to do, is get rid of all the stack overflows we produce with the above classes. The problem here is that any <strong>JarFileClassLoader</strong> asks its parent, the <strong>PluginLoader</strong>, to load a class. This will ask all child <strong>JarFileClassLoaders</strong> to load the class including the CL which asked the <strong>PluginLoader</strong> before. The result is an infinite call stack loop &#8211; a stack overflow. Therefore we relax the concept of the java class loading. We introduce a method <strong>loadClassSimple(String)</strong> on the <strong>JarFileClassLoaders</strong> which looks just in its very own jar file. If it does not find the wanted class it just throws an Exception without asking a parent or cache-lookups. This method is called by the <strong>PluginLoader</strong> only, therefore the rest of the class loading is not affected.<br />
<img src="http://www.techjava.de/wp-content/uploads/PluginClassLoader/pluginclassloader_instance.png" alt="Plugin Class Loader at runtime" style="float:right; margin:5px" /><br />
Last but not least we consider some performance issues. If a class is searched in other jar files, those have to be scanned every time again resulting in poor performance. Therefore we introduce a cache in the <strong>JarFileClassLoader</strong> containing every class that was loaded before. Every request is served now by trying to find the class in the cache first. </p>
<h3>Limitations</h3>
<p>Due to the fact, that <strong>PluginLoader</strong> asks its child <strong>JarClassLoaders</strong> to load a class in particuliar order, and the first class found will be taken, the order in which <strong>JarClassLoaders</strong> are asked matters. This issue can cause problems if e.G. different versions of the same library are deployed on location scanned by the <strong>PluginLoader</strong> and should be handled with care.</p>
<h3>References</h3>
<ul>
<li>
<div>[2007,book] 
<a  href="#2007_KRUEGER" class="toggle">bibtex</a>  
<a  href='http://www.javabuch.de/} publisher =	{Addison-Wesley} isbn =	{3-8273-2373-8' title='Go to document' onclick="javascript:pageTracker._trackPageview('/external/www.javabuch.de/} publisher =_{Addison-Wesley} isbn =_{3-8273-2373-8');" ><img src='http://www.techjava.de/wp-content/plugins/bib2html/external.png' width='10' height='10' alt='Go to document' /></a></div>
<div>G. Krueger and T. Stark, <em>Handbuch der Java-Programmierung</em>, , 2007.</div>
<div class="bibtex" id="2007_KRUEGER">
         <code>@book{2007_KRUEGER, <br />
 &nbsp;&nbsp;author =	{Guido Krueger and Thomas Stark}, <br />
 &nbsp; title =	{Handbuch der Java-Programmierung}, <br />
 &nbsp; month =	Nov, year =	{2007}, <br />
 &nbsp; url = {http://www.javabuch.de/} publisher =	{Addison-Wesley} isbn =	{3-8273-2373-8}<br />
}</code>
    </div>
</li>
<li>
<div>[,techreport] 
<a  href="#" class="toggle">bibtex</a>  
<a  href='{http://www.developer.com/java/other/article.php/2248831' title='Go to document' onclick="javascript:pageTracker._trackPageview('/external/{http//www.developer.com/java/other/article.php/2248831');" ><img src='http://www.techjava.de/wp-content/plugins/bib2html/external.png' width='10' height='10' alt='Go to document' /></a></div>
<div>&quot;Java Class Loading: The Basics,&quot;.</div>
<div class="bibtex" id="">
         <code>@techreport{CL_BASICS author =	{Brandon E. Taylor}, <br />
 &nbsp; title =	{Java Class Loading: The Basics}, <br />
 &nbsp; url = {http://www.developer.com/java/other/article.php/2248831}</code>
    </div>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2008/02/plugin-class-loader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
