Hi all,
I’m developing a Servoy plugin that uses another jar file (jmagick.jar) that uses a native library.
I’m on a Mac with Mac OS X Server 10.4.1 with Servoy Developer R2 2.2 build 328.
The layout is:
myPlugin → jmagick.jar → nativeLibrary.jnilib
The plugin works if I try it from inside XCode, but if I try to use it from a Servoy solution it displays an error in the execution of the Javascript method that calls the plugin method. If I click the Details button it displays java.lang.ExceptionInInitializerError.
If I check the Console log I see:
org.mozilla.javascript.JavaScriptException: java.lang.ExceptionInInitializerError
org.mozilla.javascript.JavaScriptException: java.lang.ExceptionInInitializerError
at org.mozilla.javascript.JavaScriptException.wrapException(JavaScriptException.java:71)
at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:366)
at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1249)
at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2031)
at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:94)
at com.servoy.j2db.scripting.e.call(Unknown Source)
at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1249)
at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2031)
at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:94)
at com.servoy.j2db.scripting.e.call(Unknown Source)
at com.servoy.j2db.develop.debugger.k.a(Unknown Source)
at com.servoy.j2db.develop.debugger.k.executeFunction(Unknown Source)
at com.servoy.j2db.FormPanel.a(Unknown Source)
at com.servoy.j2db.FormPanel.a(Unknown Source)
at com.servoy.j2db.FormPanel$b.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1882)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2202)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:234)
at java.awt.Component.processMouseEvent(Component.java:5562)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3093)
at java.awt.Component.processEvent(Component.java:5327)
at java.awt.Container.processEvent(Container.java:2010)
at java.awt.Component.dispatchEventImpl(Component.java:4029)
at java.awt.Container.dispatchEventImpl(Container.java:2068)
at java.awt.Component.dispatchEvent(Component.java:3877)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4256)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3936)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3866)
at java.awt.Container.dispatchEventImpl(Container.java:2054)
at java.awt.Window.dispatchEventImpl(Window.java:1766)
at java.awt.Component.dispatchEvent(Component.java:3877)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:267)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:182)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
java.lang.ExceptionInInitializerError
at it.melasistemi.servoy.plugin.ImageConverter.toJPG(ImageConverter.java:19)
at it.melasistemi.servoy.plugin.ServoyPluginProvider.js_createJPGImageFromPNG(ServoyPluginProvider.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:332)
at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1249)
at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2031)
at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:94)
at com.servoy.j2db.scripting.e.call(Unknown Source)
at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1249)
at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2031)
at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:94)
at com.servoy.j2db.scripting.e.call(Unknown Source)
at com.servoy.j2db.develop.debugger.k.a(Unknown Source)
at com.servoy.j2db.develop.debugger.k.executeFunction(Unknown Source)
at com.servoy.j2db.FormPanel.a(Unknown Source)
at com.servoy.j2db.FormPanel.a(Unknown Source)
at com.servoy.j2db.FormPanel$b.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1882)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2202)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:234)
at java.awt.Component.processMouseEvent(Component.java:5562)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3093)
at java.awt.Component.processEvent(Component.java:5327)
at java.awt.Container.processEvent(Container.java:2010)
at java.awt.Component.dispatchEventImpl(Component.java:4029)
at java.awt.Container.dispatchEventImpl(Container.java:2068)
at java.awt.Component.dispatchEvent(Component.java:3877)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4256)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3936)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3866)
at java.awt.Container.dispatchEventImpl(Container.java:2054)
at java.awt.Window.dispatchEventImpl(Window.java:1766)
at java.awt.Component.dispatchEvent(Component.java:3877)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:267)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:182)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
Caused by: java.lang.RuntimeException: Can't load MagickLoader (class not found)
at magick.Magick.<clinit>(Magick.java:25)
... 44 more
For what I understand, the error comes from line 25 of Magick.java, a source file of jmagick.jar.
File Magick.java contains:
package magick;
import java.awt.Rectangle;
/**
* The sole purchase of this class is to cause the native
* library to be loaded whenever a concrete class is used
* and provide utility methods.
*
* @author Eric Yeo
* @author Max Kollegov <virtual_max@geocities.com>
*/
public class Magick {
static {
String clprop = System.getProperty("jmagick.systemclassloader");
if (clprop == null || clprop.equalsIgnoreCase("yes")) {
try {
ClassLoader.getSystemClassLoader()
.loadClass("magick.MagickLoader").newInstance();
}
catch(ClassNotFoundException e) {
throw new RuntimeException("Can't load MagickLoader " + /* LINE 25 */
"(class not found)");
}
catch(IllegalAccessException e) {
throw new RuntimeException("Access to SystemClassLoader "+
"denied (IllegalAccessException)");
}
catch(InstantiationException e) {
throw new RuntimeException("Can't instantiate MagicLoader " +
"(InstantiationException)");
}
}
else {
System.loadLibrary("JMagick");
}
}
/**
* Parses a geometry specification and returns the
* width, height, x, and y values in the rectangle.
* It also returns flags that indicates which of the
* four values (width, height, xoffset, yoffset) were
* located in the string, and whether the x and y values
* are negative. In addition, there are flags to report
* any meta characters (%, !, <, and >).
* @param geometry String containing the geometry specifications
* @param rect The rectangle of values x, y, width and height
* @return bitmask indicating the values in the geometry string
* @see magick.GeometryFlags
*/
public static native int parseImageGeometry(String geometry,
Rectangle rect);
}
At line 25 a RuntimeException is thrown when a ClassNotFoundException is caught.
The ClassNotFoundException is thrown by the ClassLoader.loadClass() method call, because apparently it doesn’t find the MagickLoader class.
But I checked and in jmagick.jar the file MagickLoader.class exists.
I tried to create a JNLP launch file and to place it in the plugin folder, but the error still occurs.
It’s named myPlugin.jar.jnlp and contains:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+"
codebase="%%serverURL%%"
href="/plugins/ServoyPlugin.jar.jnlp">
<information>
<title>Servoy Thumbnail Generator</title>
<vendor>Mela Sistemi</vendor>
<offline-allowed/>
</information>
<resources>
<jar href="/lib/jmagick.jar" download="eager"/>
</resources>
<component-desc/>
</jnlp>
Obviously I placed jmagick.jar inside the lib folder of Servoy.
Any idea of what’s happening? :?