// 
//     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.
//

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

=== How can I run the installer for something else during module installation?

Sometimes you are distributing some software with your module which has its own installer, or some other similar code which needs to be run once to get everything needed installed on the user's system.  If you are distributing some software (which perhaps you did not write), and it has its own installer, it is 
less work to just run its installer to be sure it is set up correctly, than to have your module do everything which that installer does too (and possibly get something wrong).

link:http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-autoupdate-services/overview-summary.html[Autoupdate Services] primary handles NetBeans plugins based on link:DevFaqWhatIsNbm.asciidoc[NBM] packaging. 

In addition, Autoupdate Services offers the possibility to install/uninstall components which are not in NBM format. This possibility has been designed to support such use-cases - for example, to install an application Servers such as link:http://glassfish.dev.java.net[GlassFish] by running its own installer.  

Using a native installer ensures that, if there are any problems with the way the software gets installed, it is a problem with the native installer, not your code.

To enable such possibility, Autoupdate Services API provides:

* An SPI for providing such components
* A custom installer can be assigned to the component which performs installation particular component into NetBeans
* The ability to register that link:http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-autoupdate-services/org/netbeans/spi/autoupdate/UpdateProvider.html[special provider] among other of providers - a common Update Center

==== How to setup a Update Provider providing custom components?

Implement interface link:http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-autoupdate-services/org/netbeans/spi/autoupdate/UpdateProvider.html[UpdateProvider] to make a provider for your component that has its own installer. This provider has to:

* Determine if the component is already installed on the target system. 
* If so, it should be able to tell which version, so the system knows if the bundled version is older, newer or the same version
* Offer a component which is available to be installed into system,
* Assign a specific *installer* which can install available components,
* assign a specific *uninstaller* which can uninstall such component if is already installed
* Register the application (i.e. store a path to the installed copy of the application) so that, at runtime, code that needs to use the custom-installed software can find it

==== A code snippet showing that provider

[source,java]
----

public class FooNativeComponentProvider implements org.netbeans.spi.autoupdate.UpdateProvider {...}
----

It has simple methods describing the provider, like this:

[source,java]
----

    public String getName () {
        return "Foo Update Provider";
    }

    public String getDisplayName () {
        return getName ();
    }

    public String getDescription () {
        return "Providing components with custom installers";
    }

    public CATEGORY getCategory () {
        return CATEGORY.STANDARD;
    }
----

The essential method *`getUpdateItems`* will return link:http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-autoupdate-services/org/netbeans/spi/autoupdate/UpdateItem.html[UpdateItems] which matches these components. It has to return an `UpdateItem` both for installed component and for available component what has not been installed yet.

[source,java]
----

    public Map<String, UpdateItem> getUpdateItems () throws IOException {
        Map<String, UpdateItem> res = new HashMap<String, UpdateItem> ();


        // 1. provide already installed version

        // get installed version
        String installed = NbPreferences.forModule (FooNativeComponentProvider.class).get (FOO_CODE_NAME, null);

        // some foo-native-runtime is installed
        if (installed != null) {
            res.put (FOO_CODE_NAME + installed, getInstalledUpdateItem (installed));
        }

        // 2. provide also version available to install

        // for this example: If none version hasn't been installed yet then provider the version 3.0
        if (installed == null) {
            res.put (FOO_CODE_NAME + "_3.0", getAvailableUpdateItem ("3.0"));

        // if the version 3.0 is installed then provide newer version 3.1
        } else if ("3.0".equals (installed)) {
            res.put (FOO_CODE_NAME + "_3.1", getAvailableUpdateItem ("3.1"));
        }
        
        return res;
    }
----

There are two factory methods *`getInstalledUpdateItem`* and *`getAvailableUpdateItem`*.  Both are using SPI link:http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-autoupdate-services/org/netbeans/spi/autoupdate/UpdateItem.html#createNativeComponent(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.util.Set,%20java.lang.String,%20java.lang.String,%20java.lang.Boolean,%20java.lang.Boolean,%20java.lang.String,%20org.netbeans.spi.autoupdate.CustomInstaller,%20org.netbeans.spi.autoupdate.UpdateLicense)[UpdateItem.create(Installed)NativeComponent]

Add an `UpdateItem` matching available component first.  The provider has to specify a name, display name, download size and so forth. 

The most important parts are link:http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-autoupdate-services/org/netbeans/spi/autoupdate/CustomInstaller.html[CustomInstaller] and link:http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-autoupdate-services/org/netbeans/spi/autoupdate/CustomUninstaller.html[CustomUninstaller]. For example:

[source,java]
----

    private static UpdateItem getAvailableUpdateItem (String specificationVersion) {
        String displayName = "Foo Runtime " + specificationVersion;
        String description = "Foo Runtime " + specificationVersion + " with native installer";
        String downloadSize = "2815";
        CustomInstaller ci = FooInstaller.getInstaller ();
        assert ci != null;
        UpdateLicense license = UpdateLicense.createUpdateLicense ("none-license", "no-license");
        UpdateItem item = UpdateItem.createNativeComponent (
                                                    FOO_CODE_NAME,
                                                    specificationVersion,
                                                    downloadSize,
                                                    null, // dependencies
                                                    displayName,
                                                    description,
                                                    false, false, "my-cluster",
                                                    ci,
                                                    license);
        return item;
    }
----

Now, for an already-installed copy of the software:

[source,java]
----

    private static UpdateItem getInstalledUpdateItem (String specificationVersion) {
        String displayName = "Foo Runtime " + specificationVersion;
        String description = "Foo Runtime " + specificationVersion + " with own installer";
        CustomUninstaller cu = FooUninstaller.getUninstaller ();
        assert cu != null;
        UpdateItem item = UpdateItem.createInstalledNativeComponent (
                                                    FOO_CODE_NAME,
                                                    specificationVersion,
                                                    null, // dependencies
                                                    displayName,
                                                    description,
                                                    cu);
        return item;
    }
----

So, what does a custom installer look like? It it quite simple, look on

[source,java]
----

public class FooInstaller implements org.netbeans.spi.autoupdate.CustomInstaller {
    /** This code will be called back while installing the corresponding native component
     * from Plugin Manager Install Wizard.
     */
    public boolean install (String codeName, String specificationVersion, ProgressHandle handle) throws OperationException {
        // CustomInstaller has to start `org.netbeans.api.progress.ProgressHandle` !!!
        handle.start ();

        // a custom code which invokes installation of native component actually
        .......
    }
}
----

==== How to register UpdateProvider in my application?

Using link:DevFaqModulesGeneral.asciidoc[META-INF/services] or (in NetBeans 6.9) the `@ServiceProvider` annotation (see link:https://blogs.oracle.com/geertjan/entry/meta_inf_services_vs_layer[Geertjan's blog for more info]):

1. Make a `META-INF/services` folder in sources of your NetBeans project where the provider is,
2. Make a file `org.netbeans.spi.autoupdate.UpdateProvider` in this folder,
3. Type name of class where `UpdateProvider` implemented, i.e. org.netbeans.modules.fooupdateprovider.FooNativeComponentProvider

And , that's it, the NetBeans Lookup system will read it and includes that provider among other providers registered in NetBeans application.

==== A sample project having this UpdateProvider

* Sources of `Foo Native Component Provider`: link:Media:fooupdateprovider_FaqDevComponentWithCustomInstaller.zip.asciidoc[fooupdateprovider_FaqDevComponentWithCustomInstaller.zip]
* Binary NBM to playing with: link:Media:org-netbeans-modules-fooupdateprovider_FaqDevComponentWithCustomInstaller.nbm.asciidoc[org-netbeans-modules-fooupdateprovider_FaqDevComponentWithCustomInstaller.nbm]

==== Important Note

Don't apply this Update Provider earlier than NetBeans 6.5 release will be out. There were several problem which had to be fixed in NetBeans 6.5. Use link:http://www.netbeans.org/downloads/index.html[NetBeans 6.5] or some of recent link:http://bits.netbeans.org/dev/nightly/latest/[Development builds] rather than previous releases 6.1 or 6.0!

-
Do not hesitate to contact me on mailto:jrechtacek@netbeans.org if you have any question.

=== 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/DevFaqUseNativeInstaller[http://wiki.netbeans.org/DevFaqUseNativeInstaller] , 
that was last modified by NetBeans user Skygo 
on 2013-12-17T22:12:04Z.


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