// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= DevFaqLookupDefault
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqLookupDefault
:description: Apache NetBeans wiki DevFaqLookupDefault
:toc: left
:toc-title:
:syntax: true

=== What is the "default lookup"?

The default lookup is `Lookup.getDefault()`.
It is the registry for global singletons and instances of objects which have been registered in the system by modules.
(In JDK 6, `ServiceLoader` operates on the same principle.)
The default lookup searches in two places:

* The link:http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/Lookups.html#metaInfServices(java.lang.ClassLoader)[META-INF/services/ Lookup] contains all objects registered by modules via the link:http://java.sun.com/j2se/1.4/docs/guide/extensions/[Java Extension Mechanism] - putting files in the `META-INF/services/` directory of their module JARs (typically done using the [link:http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/ServiceProvider.html[http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/ServiceProvider.html] `@ServiceProvider`] annotation)
* The contents of the `Services/` folder of the link:DevFaqSystemFilesystem.asciidoc[System (configuration) Filesystem] (this is harder and somewhat deprecated)

Objects contained in the default lookup are instantiated lazily when first requested.  Objects returned by the default lookup _may_ (or may not) be garbage collected if they become unreferenced.

Here is the usual usage pattern:

1. A central "controller" module defines some interface, e.g.

[source,java]
----

package controller.pkg;
public interface MyService {
    void doSomething();
}

----


[start=2]
. Each module which wants to implement that service depends on the controller module which defines the interface, and creates and registers an implementation:

[source,java]
----

@ServiceProvider(service=MyService.class)
public class MyImpl implements MyService {
    public void doSomething() {....}
}

----

It is also possible to declaratively mask other people's implementations and declaratively order implementations so some will take precedence.


[start=3]
. The controller finds all implementations and uses them somehow:

[source,java]
----

for (MyService s : Lookup.getDefault().lookupAll(MyService.class)) {
    s.doSomething();
}

----

=== More About Lookup

* link:DevFaqLookup.asciidoc[DevFaqLookup]
* link:http://bits.netbeans.org/dev/javadoc/usecases.html#usecase-Utilities[Extension Points Tutorial] 
* link:http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/Lookup.html[Javadoc for Lookup]

<hr/>

Applies to: NetBeans 6.7 and later

=== Apache Migration Information

The content in this page was kindly donated by Oracle Corp. to the
Apache Software Foundation.

This page was exported from link:http://wiki.netbeans.org/DevFaqLookupDefault[http://wiki.netbeans.org/DevFaqLookupDefault] , 
that was last modified by NetBeans user Jtulach 
on 2010-07-24T20:14:14Z.


*NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed.
