Jump to content
Excelsior Forums
uditha

Bug or My mistake

Recommended Posts

I'm working on an application which has to support plugins like feature. For example, when I put a class (or a dll)  in to the Plugins folder of the application must load it and activate the plugin. I was able to implement this feature without a problem with java, but does not work when compiled with jet ( I tried with both Jet Pro. versions of 2.51 and 3.0)

   1. Once the application is started it loads both plugins (P1, P2) using class.forname()

           Class x = Class.forName(files);

   2. Each plugin is casted to Plugin interface

           myplugin.Plugin c = (myplugin.Plugin) x.newInstance();

           above line works fine with Java 1.4.1 and 1.4.1_01 but not with Jet Professional 2.51 and 3.0

            error --> java.lang.ClassCastException: myplugin.P1

---- Pligin1 class ------------------------------

[tt]

package myplugin;

public class P1 implements Plugin{

 public P1() {

 }

 public int getValue(){

   System.err.println("invoked P1");

   return 5;

 }

 public void init(){

     System.err.println("Hi, I'm P1");

 }

}

--------- Plugin interface ----------

package myplugin;

public interface Plugin {

   public void init();

}

----- Main (parent) class ------------

package myapp;

import myplugin.*;

public class parent {

 public parent() {

   try {

     String[] files = {"myplugin.P1","myplugin.P2"};

     for (int i = 0; i < files.length; i++) {

         Class x = Class.forName(files);

         System.err.println("loaded : " + x.getName());

         myplugin.Plugin c = (myplugin.Plugin) x.newInstance();

         c.init();

         c=null;

     }

   }

   catch (Exception ex) {

     ex.printStackTrace();

   }

 }

 public static void main(String[] args) {

   parent parent1 = new parent();

 }

}

Both P1 and P2 classes are similar except system.outs

[/tt]

This is how I implemented the Jet compiled version

   I created the parent EXE with parent.class and Plugin.class

   Created 2 dlls

        P1.dll --> P1.class, Plugin.class

        P2.dll --> P2.class, Plugin.class

  I can see dlls loading with class.forname() but the casting in step 2 above fails when using dlls. But it works without a problem if I create a single application with all classes.

 Is this a bug or is it that I do not know how to create DLLs.

Please help

[tt]

--- Project files -------

P1.prj

-GENDLL+

-DLLNAME=P1

-lookup=*.class=..\classes

!module myplugin/P1

--------------------------------

parent.prj

-main=myapp/parent

-lookup=*.class=..\classes

[/tt]

Share this post


Link to post
Share on other sites

Hello, Uditha.

You have included Plugin.class into both dlls and into exe thus creating three different classes in fact.

Plugin.class should be located in a single component, probably dll, and all other components (dlls and exe) should use this dll.

Consult JET User's Guide for more information about compiling multi-component applications. Also, you may take a look at JET\samples\DLL for some examples.

-AlexM

Share this post


Link to post
Share on other sites

Hi

   Now I have a nother problem in my plugin enabled application. I can use Class.forname to load classes in my plugin dlls, but I can only do that if I have JETVMPROP=-dll.... entry.

   My requirement is to scan the Plugins folder in of application and dynamically load any dlls in it (in this case plugin class name is equal to the dll name).  Therefore I cannot use the JETVMPROP setting since number of plugins in the folder may vary for each user.

Note: plugins are downloaded automatically by the application depending on the user's subscription level.

How can I get this Dynamic dll loading feature.

Please help

Share this post


Link to post
Share on other sites

Hello, Uditha.

For the JET to load DLL automatically in case of Class.forName request, the class to dll mapping should be specified in JETVMPROP (project file equation or environment variable).

But you know name of DLL at run-time (File.list()), so

you can write a native method, which use LoadLibrary from Windows API to load JET-compiled dll. After loading, all classes from that dll may be found via Class.forName().

Here is the source for such native method:

1. loaddll.c

#include <jni.h>

#include <windows.h>

JNIEXPORT void JNICALL Java_LoadDLL_loadDLL0 (JNIEnv *ee, jclass clazz, jbyteArray name)

{

   byte * nm = (*ee)->GetByteArrayElements (ee, name, 0);

   LoadLibrary (nm);

   (*ee)->ReleaseByteArrayElements (ee, name, nm, JNI_ABORT);

}

2. LoadDLL.java

public class LoadDLL {

   private static native void loadDLL0 (byte [] name);

   public static void loadDLL (String name)

   {

        loadDLL0 (name.getBytes());

   }

}

-AlexM

Share this post


Link to post
Share on other sites

×