Extending the Lookup of a Java SE Project

Here I have the start of some kind of visualizer for Java SE projects in NetBeans IDE. A project is passed in and then the visualizer does something with it:

public class MyJavaSEVisualizer {

    public MyJavaSEVisualizer(Project p) {
        // do something with the project to visualize it

Next, I have some action. In this case, the action is invoked from the File menu. The action is only enabled if a project is in the lookup. The action then retrieves the visualizer from the lookup of the project:

@ActionID(category = "File", id = "org.jse.lookup.SomeAction")
@ActionRegistration(displayName = "#CTL_SomeAction")
@ActionReference(path = "Menu/File", position = 0)
public final class SomeAction implements ActionListener {
    private final Project context;

    public SomeAction(Project p) {
        this.context = p;

    public void actionPerformed(ActionEvent e) {
        MyJavaSEVisualizer mjsev = context.getLookup().lookup(MyJavaSEVisualizer.class);
        if(mjsev != null){
            JOptionPane.showMessageDialog(null, "this is a Java SE project");
            // now call a method on mjsev...
        } else {
            JOptionPane.showMessageDialog(null, "this is NOT a Java SE project");
            // now don't call a method on mjsev...

But how does the visualizer end up in the lookup of the project? Like this, i.e., without changing the source of Java SE projects, but by extending the lookup of Java SE projects, i.e., the lookup of projects can be defined to be pluggable and, in the case of NetBeans IDE projects, projects have been defined in that way:

@LookupProvider.Registration(projectType = "org-netbeans-modules-java-j2seproject")
public class MyJavaSEVisualizerLookupProvider implements LookupProvider  {

    public Lookup createAdditionalLookup(Lookup lookup) {
        return Lookups.fixed(new MyJavaSEVisualizer(lookup.lookup(Project.class)));

Interesting, this is the same kind of Lookup injection we use in some of our own internal code (based on a different container type than Project). This is exactly the kind of scenario where, if the instantiation of MyJavaSEVisualizer could potentially be expensive, letting createAdditionalLookup() return a Lookup with lazily initialised contents could be advantageous performance-wise.

Posted by Ernest on July 18, 2012 at 07:22 PM PDT #

Thanks for the blog. In my case everything was fine, just needed to make one of the modules eager for everything to work!

Posted by Javier Ortiz on July 19, 2012 at 09:14 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.


« April 2014