★ wanayoo — archive 1999 http://developer.iplanet.com/viewsource/naru_plugins/naru_plugins.htmlNouvelle recherche | Portail wanayoo
iPlanet

You are here:  Home > Developers > View Source Articles > Plug-in View Source Article
Plug-in View Source Article
 iPlanet Developers


Developer Program
  Membership
  One-to-One Support
  Newsgroups
  Member Services

Developer Publications
  View Source
  Developer News

Documentation
  Technical Manuals
  White Papers
  TechNotes
  Sample Code
  FAQs
  Books

Technologies
  Application Server   CSS
  DOM
  CORBA
  Directory & LDAP
  Dynamic HTML
  Java
  JavaScript
  Linux
  RDF
  Security
  SSJS
  XML
  XUL

Developer Downloads
  Tools & SDKs
  Patches

iPlanet Products
  Technical Resources










spacer
Netscape Client Plug-ins

By S. Narayanan


Send comments and questions about this article to View Source.
Click here for printer-friendly version

Netscape's plug-in architecture allows developers to extend the capabilities of Navigator, Netscape's Web browser. Using Netscape's LiveConnect technology, you can deliver high-performance applications, integrating client plug-ins with Java and JavaScript.

This article presents an overview of how to develop a plug-in that supports LiveConnect and take advantage of the resulting communication capabilities among Java, JavaScript, and C.

ABOUT PLUG-INS, MIME TYPES, AND LIVECONNECT

Plug-ins are like helper applications that run within Navigator. Although they behave as though they're part of Navigator, plug-ins are separate code modules that extend Navigator's capabilities by allowing it to support additional MIME types, play audio and video, display animations, and so on.

MIME (Multipurpose Internet Mail Extensions) media types specify most data types on the Internet, and consist of a major type (such as application, image, or text) followed by a minor type. If you create a new MIME type, you should register it with the Internet Engineering Task Force (IETF). Until the MIME type is registered, you should prefix it with x-. (For more information on MIME types, see RFC 1521.)

LiveConnect is a Netscape technology that enables communication between Java, JavaScript, and C. With LiveConnect:

  • Java can use the power of JavaScript to access browser-related information.
  • JavaScript can use Java methods, variables, classes, and packages directly.
  • Java can call native methods to export low-level functionality.
  • JavaScript can call native methods through Java.

LiveConnect is enabled by default in Navigator 3.x and later; users can manually enable it or disable it through a preference panel. LiveConnect communication is made possible in Navigator through netscape packages present in java_30 in Navigator 3.x or java40.jar in Communicator.

Because LiveConnect allows you to integrate plug-ins with Java and JavaScript, you can create LiveConnect-enabled plug-ins that are controlled by Java and JavaScript. These plug-ins can even make use of the built-in Java and JavaScript methods directly. Although no direct communication can occur between JavaScript and native methods, JavaScript can communicate with native methods through Java. (The section LiveConnect Technology presents more details on these communication capabilities.)

HOW PLUG-INS WORK

When the browser starts up, it checks for plug-in modules in the plug-ins directory and registers them. (You can find the installed plug-ins by selecting About Plug-ins from the Help menu.) When an unknown MIME type comes over the stream, Navigator checks for that type in the header. If a plug-in is available to handle the new stream with the specified MIME type, then Navigator loads the appropriate plug-in into memory, creates a new instance of it, initializes it, and hands the new stream over to the plug-in. Navigator also gives the window handle to the plug-in so that it can draw in the Navigator window.

Plug-ins can also be loaded as part of a Web page by means of the EMBED tag. If you use the SRC parameter in your EMBED tag, Navigator looks at the type of document to decide which plug-in to use (which is why you need to register for MIME types and file extensions in the plug-in's resource file). When downloading a file from a Web server, Navigator receives a MIME type, which it will use to choose the plug-in. When SRC refers to a local file, there is no MIME type information, so Navigator has to fall back on the extensions that plug-ins have registered for.

DEVELOPING A 32-BIT PLUG-IN USING MICROSOFT VISUAL C++ 4.0

The following steps give a general description of how to develop a 32-bit Navigator plug-in using Microsoft Visual C++ 4.0. (These steps are for Windows development only.)

Note: These steps are intended specifically for developing a plug-in with Microsoft Visual C++. However, you can use the Plug-in SDK in any C++ development environment.

  1. Open a new project workspace.
  2. Select MFC AppWizard dll.
  3. Name the project. Make sure that the name starts with NP.
  4. Click Create.
  5. Click Finish to generate project files.
  6. Unzip the source files and copy them to your current project directory.
  7. Insert WinTemp.c and npwin.cpp into your project.
  8. Open the VS_VERSION_INFO resource file in the Visual C++ resource editor.
  9. Double-click Block Header. In the dialog box that appears, specify Code Page as Windows, Multilingual. (If you don't do this, Navigator won't recognize your plug-in.)
  10. Save and open your resource (.rc) file in Notepad to add MIME and file extension information.
  11. Add the following in your .rc file below VALUE "CompanyName", "\0":
  12. VALUE "FileExtents", "wpt\0"
    VALUE "FileOpenName", "Windows Plugin Template (*.wpt)\0"
    VALUE "MIMEType", "application/x-Netscape-Windows-Plugin-Template\0"
  13. Save the file and close Notepad. Open VS_VERSION_INFO in Visual C++. You should see the new values. You can change the MIME types and file extensions according to your needs; for the purpose of this example, however, leave them unchanged.
  14. >From the Build menu, choose Settings to display the Open Project Settings dialog box.
  15. Under General, select "Use MFC in a Static Library." This is necessary to avoid shipping additional libraries with your plug-in.
  16. Open the C/C++ folder.
  17. Select Precompiled Headers from the Category list.
  18. Select Automatic Use Of Precompiled Headers, and click OK.
  19. Open the module definition (.def) file in Visual C++.
  20. Delete EXPORTS and any explicit exports that follow.
  21. Add the following code:
  22. CODE  PRELOAD MOVEABLE DISCARDABLE
    DATA  PRELOAD SINGLE
    EXPORTS
       NP_GetEntryPoints  @1
       NP_Initialize               @2
       NP_Shutdown          @3
  23. Build your plug-in DLL (dynamic linked library).
  24. Copy the plug-in DLL into your plug-ins directory. Then, if Navigator is running, restart it.
  25. Unzip the test files. Open TemplateExample.html in Navigator.

Once you've completed these steps, you'll have a basic plug-in module. The rest of this article describes LiveConnect technology in general and shows how to extend the plug-in you just built to support LiveConnect.

LIVECONNECT TECHNOLOGY

This section describes how Netscape's LiveConnect can be used to connect Java, JavaScript, and plug-ins.

JavaScript-to-Java Communication

JavaScript can call Java built-in functions directly. To access Java in JavaScript, use the following syntax:

[Packages.]packageName.className.methodName
  • Packages is optional; it can refer to Java, Netscape, or Sun.
  • packageName refers to the package name.
  • className refers to a particular class in the package.
  • methodName refers to a method in the class.

Here's how JavaScript uses the println() method of Java's System class to print to the Java Console (a Navigator window that displays Java messages printed to stdout()).

java.lang.System.out.println("Greetings from JavaScript");

Example 1 demonstrates how to access the Java built-in classes directly. It uses Java's built-in Math class to calculate the power of two numbers. 

Similarly, JavaScript can control Java applets. JavaScript can reference applets present in the document using the applets array or the applet's name. Using this reference, JavaScript is able to access an applet's public members and methods.

Example 2 demonstrates how JavaScript can access an applet's public members and public methods.

Java-to-JavaScript Communication

The Netscape JavaScript package contains JSObject and JSException classes. To access JavaScript functions and properties in Java, import the JavaScript package into your Java code. To allow your applet to use JavaScript, you must specify the MAYSCRIPT attribute in the APPLET tag. This prevents an applet from accessing JavaScript without the knowledge of the page's author. If MAYSCRIPT is not specified, an exception is thrown for applets using JSObject. (MAYSCRIPT is only needed for Java to access JavaScript -- not for JavaScript to access Java.)

Before accessing JavaScript properties or functions, you must get the browser window handle. You can do this by using the JSObject class's getWindow() method.

JSObject winHandle = (JSObject) JSObject.getWindow(this);

In the above code, this represents the Applet object.

Once you obtain the browser window handle, you can use the JSObject.getMember() method to access JavaScript properties. Example 3 shows how to use JSObject.getMember().

Applets can also execute JavaScript functions using the JSObject.eval() and JSObject.call() methods. Example 4 demonstrates how a Java applet uses these methods to call JavaScript built-in functions. 


Java-to-C Communication

Writing native methods primarily allows you to export low-level functionality that Java may not provide. You can also use native methods to provide better performance.

The following steps present a generic way of defining and using native code in Java. (Details on calling a plug-in's native methods from Java are given later in this article.)

  1. Create a Java class that declares a native method.
  2. Compile your Java code using javac.
  3. Create .h and .c files using the javah utility.
  4. The .h file you created will have the C syntax for your native function. Implement native methods using this function declaration.
  5. Create a DLL.
  6. Load the DLL into your Java code to access the native method.

For more information, check Sun's example in the article Integrating Native Code and Java Programs.

Note: Although Java applications can load DLLs to call native methods, security restrictions prevent applets from doing so. With LiveConnect, however, it is possible for an applet to execute a plug-in's native methods as long as the plug-in and applet are loaded.

JavaScript-to-C Communication

For security reasons, JavaScript cannot call the native code directly. But since JavaScript can call Java directly, it can call the native code through Java.

ENABLING NETSCAPE CLIENT PLUG-INS TO SUPPORT LIVECONNECT

This section begins by giving an overview of Netscape's Plugin class and javah utility, which allow you to support LiveConnect and call native methods from Java. At the end of the section, you'll find steps for implementing LiveConnect support in the plug-in you built earlier.

The Netscape Plugin Class

For security reasons, applets cannot load DLL modules to call native functions. But with Netscape's LiveConnect, you can call plug-in native code through the Plugin peer class. (After reading this article, you may want to refer to the PluginAppletComm example to see how applets can communicate with LiveConnect plug-ins; this example was tested on Netscape Navigator 3.x with the Simple plug-in.)

The Plugin class, provided by Netscape, extends the Object class of Java. The Plugin class represents the Java reflection of the plug-in. If you develop LiveConnect plug-ins, you'll have to design a Java class derived from Plugin to add new methods; these methods can be native methods that will be defined in plug-in code, or they can be any normal Java methods that can use other Java classes. This allows Java applets and JavaScript to manipulate or call plug-in functions.

For more information, see the description of the Plugin class in the JavaScript Guide.

Netscape's Javah Utility

LiveConnect is built on the Java Runtime Interface (JRI). But the JRI implementation is hidden when you use Netscape's javah utility, a modified version of Sun's javah. (For complete documentation on JRI, check the Additional Resources section of the LiveConnecting Plug-ins with Java.) Netscape's javah, provided along with the plug-in developer's kit, allows you to write native methods that are independent of the structure and implementation of Java objects. You can use the javah utility to generate a corresponding .c file and .h file for a given Java class file. These files have native method declarations that are to be used for defining native methods in the plug-in; they also have declarations for calling Java methods or for accessing Java fields. You must include these files with your plug-in code for compiling and linking.

The Java Runtime Interface document contains details on javah-generated header files and stub files.

Netscape LiveConnect Communication

Netscape LiveConnect technology is restricted to plug-ins, Java, and JavaScript communication. As mentioned earlier, security considerations prevent Java applets from loading native code modules to execute native methods. Instead, Java and JavaScript can use the native code of the loaded plug-in module. With Netscape LiveConnect:

  • Java and JavaScript can call a plug-in's native code.
  • Plug-ins can call Java and JavaScript.

Communication between JavaScript and plug-ins can only occur through Java.

Calling Java Methods from Plug-ins

To use a built-in Java method or access its properties in your plug-in, follow these steps:

  1. Run Netscape's javah on the Java class you want to use. For example, if you want to use the String class, javah -jri java.lang.String would generate java_lang_String.h, and javah -jri -stubs java.lang.String would generate java_lang_String.c.
  2. Include these javah-generated files in your plug-in code for compiling and linking.
  3. Use the function definition in *.h (java_lang_String.h) to call the class methods directly from the plug-in.
  4. Call the use_ method to create an instance of the String class during run time.

For more details, see the document Calling Java Methods from Plug-ins.

Calling Plug-in Methods from Java

Some Java methods can be written in native code. This article discusses plug-in native code executed from Java applets. You can read more about Sun's implementation in the article Integrating Native Code and Java Programs.

To allow Java to access a plug-in's native methods, you need to supply a Java class that is a subclass of Netscape's Plugin class. Here are the steps involved:

  1. Derive a Java class from Plugin. This class must be a public class; otherwise, you'll get a run-time error.
  2. Declare native methods in the Java class.
  3. Compile the Java file to generate the byte file.
  4. Run Netscape's javah on the byte file to create the .h and the .c files corresponding to the class name.
  5. Include these files in your plug-in files.
  6. Define the native method.
  7. Call the use_ method to create an instance of the Java class during run time.
  8. Call native methods directly from your Java class.

Now when Java calls the native Java method, your plug-in's native code is executed. (You'll also develop a live example later, in the section Changes to Make in Your Plug-in Files.)

Calling Plug-in Methods from JavaScript

Because Netscape's LiveConnect technology permits JavaScript to call a Java method, JavaScript can execute native code through Java.

All LiveConnect plug-ins will have a Plugin peer class, so JavaScript can directly call into the public methods of this peer class using the following syntax:

document.pluginName.methodName

This will directly execute your Java method or your plug-in native code, depending on which method you call.

Changes to Make in Your Plug-in Files

To implement LiveConnect in the plug-in files you built in Visual C++, you must supply a plug-in class that you derive from Netscape's Plugin class. In the following steps, MyClass represents the class you're supplying.

  1. Define a plug-in class that will support LiveConnect functionality, as shown here. Copy the following code and save it as MyClass.java:
  2. import netscape.plugin.Plugin;
    public class MyClass extends Plugin{ 
    public native void popWindowsMessageBox(); 
    }
  3. Obtain the MyClass.class file by running javac, and obtain the corresponding MyClass.h and MyClass.c files by running Netscape's javah. Copy MyClass.c and MyClass.h into your project directory. (For the javah syntax, see the next step.)
  4. You will also need to generate java_lang_Object.h, netscape_plugin_Plugin.h, and netscape_plugin_Plugin.c under your project directory, because they are dependent files. Use the following commands:
  5. javah -jri java.lang.Object
    javah -jri netscape.plugin.Plugin
    javah -jri -stubs netscape.plugin.Plugin
  6. Make sure CLASSPATH points to java_30 or java40.jar. If you get a -jri illegal argument message, then you are not using Netscape's javah -- you're using Sun's javah.
  7. In Visual C++, create a new file by copying the following code and saving it as stubs.c. (Note: Although it's not usual practice, the .c files are included here to avoid some fancy "make" rules.)
  8. #include "netscape_plugin_Plugin.c" 
    #include "MyClass.c"
  9. Insert stubs.c into the project that you have already built.
  10. Open WinTemp.c. This is the file in which you will define your native method. Under the line #include <windows.h>, type the following code:
  11. #define IMPLEMENT_MyClass 
    #include "MyClass.h"
    #include "netscape_plugin_Plugin.h"
  12. Call use_  in NPP_GetJavaClass() for all the Java classes that you want to use in your plug-in code. This associates your Java class with your plug-in. In NPP_GetJavaClass(), return the class you derived from the Plugin class. If you don't intend to associate any Java classes in your plug-in, return NULL in NPP_GetJavaClass(). Here's the code you'll add to your NPP_GetJavaClass():
  13. struct java_lang_Class* myClass; 
    JRIEnv* env = NPN_GetJavaEnv(); 
    if (env == NULL) 
     return NULL;  /* Java disabled */ 
    myClass = use_MyClass(env); 
    use_netscape_plugin_Plugin( env ); 
    return myClass;
  14. When you finish, call the corresponding unuse_ routine to unload your classes in NPP_Shutdown(void). Here's what you have to add to this example:
  15. JRIEnv* env = NPN_GetJavaEnv();
    if (env) { 
          unuse_MyClass(env); 
          unuse_netscape_plugin_Plugin( env ); 
    }
  16. If you don't intend to associate any Java classes in your plug-in, return NULL in NPP_GetJavaClass().
  17. Now define your native method in WinTemp.c. Here's a sample snippet:
  18. extern JRI_PUBLIC_API(void) 
    native_MyClass_popWindowsMessageBox(JRIEnv* env, struct MyClass* self){ 
         NPP npp = (NPP)netscape_plugin_Plugin_getPeer(env, self); 
         PluginInstance *pinst = (PluginInstance*)npp->pdata; 
         NPWindow *window = pinst->fWindow; 
         MessageBox((HWND)window->window, "Test", "Native", MB_OK); 
    }
  19. Compile your plug-in. Copy the plug-in DLL and MyClass.class into your plug-ins directory. Modify your test file (TemplateExample.html). You may want to include some test code like this:
    <form> 
    <input type=button Value=click onClick="document.embeds[0].popWindowsMessageBox();"> 
    </form>


Technical reviewers for this article were Sharon Williams, Marc Byrd, Steve Thomas, and Eric Byunn of Netscape Communications. The article was edited by Anne Szabla.


FURTHER READING


View Source wants your feedback!
Write to us and let us know
what you think of this article. 

S. Narayanan is a software engineer at India-based Wipro Systems and works as a developer support engineer for Netscape. Narayanan specializes in Netscape's client technologies. He has also contributed sample code and FAQ documents to Netscape's developer site. 

(7.97)


Related Readings:


Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use

spacer spacer


                                                       
iPlanet International | Year 2000 | Site Map | Feedback
Products | Solutions | Support | Services | Download | About Us | Developer
© 2000 Sun-Netscape Alliance. All Rights Reserved  Privacy Policy