Dev : Extensions : Example Code : Calling Java from Javascript: Difference between revisions

From MozillaZine Knowledge Base
Jump to navigationJump to search
No edit summary
m (removed link to xulplanet)
 
(3 intermediate revisions by 2 users not shown)
Line 25: Line 25:
jvm.showJavaConsole();
jvm.showJavaConsole();
</pre>
</pre>
http://www.xulplanet.com/references/xpcomref/ifaces/nsIJVMManager.html#method_showJavaConsole


 
Here's the code I use to log exceptions.  JSUtil.getStackTrace doesn't always work.  I haven't figured out why, so I do it last, wrap it in a try catch, and print out my own "rough" stack trace first.  (The rough list has no line numbers.)
Here's the code I use to log exceptions.  getStackTrace doesn't always work.  I haven't figured out why, so I do it last, wrap it in a try catch, and print out my own "rough" stack trace first.  (No line numbers.)
Wrap all java calls in a try catch and log the exception.  Mozilla doesn't always report them and when it does it doesn't give the stack trace, and it's usually wrapped in a meaningless exception.  I think the java console logs all exceptions though, so maybe this isn't necessary if you use that.
Wrap all java calls in a try catch and log the exception.  Mozilla doesn't always report them and when it does it doesn't give the stack trace, and it's usually wrapped in a meaningless exception.
<pre>
<pre>
function logExc(e) {
function logExc(e) {
Line 49: Line 47:


I'm still trying to figure out how to get my classes in the regular classpath so I can access them with "Packages" and not use reflection.  I tried setting the classpath and it doesn't work.
I'm still trying to figure out how to get my classes in the regular classpath so I can access them with "Packages" and not use reflection.  I tried setting the classpath and it doesn't work.
If you use the URLClassLoader to create an instance of a class, you can call methods on it normally.  So you can say "var myclass = class.newInstance()" and then call instance methods on my class.  That way you don't have to use reflection for everything.




Line 55: Line 54:


To get the Java plugin working in Thunderbird, I had to make a ".plugins" directory in ~/.mozilla (not ~/.thunderbird), and symlink libjavaplugin_oji.so in that directory.  Make sure you use one compiled with the same gcc as the thunderbird compile.  It also seemed to care that it was a symlink and not a copy of the lib.so file; a copy didn't work for me until I symlinked it.
To get the Java plugin working in Thunderbird, I had to make a ".plugins" directory in ~/.mozilla (not ~/.thunderbird), and symlink libjavaplugin_oji.so in that directory.  Make sure you use one compiled with the same gcc as the thunderbird compile.  It also seemed to care that it was a symlink and not a copy of the lib.so file; a copy didn't work for me until I symlinked it.
[[Category:Example code]]

Latest revision as of 18:42, 22 April 2015

This page is currently notes of what I had to do to call Java from Javascript from Thunderbird.

Here's an example from a blog: http://mozilla-firefox-extension-dev.blogspot.com/2004/11/calling-java-code-in-custom-jars-from.html

   var cl = new Packages.java.net.URLClassLoader(
       [
           new Packages.java.net.URL(
               'http://foo.net/bar.jar')
       ]
   );

   var aClass = Packages.java.lang.Class.forName("HelloWorld", true, cl);
   var aStaticMethod = aClass.getMethod("getGreeting", []);
   var greeting = aStaticMethod.invoke(null, []);
   alert(greeting);


In order to write to the file system, I had to add this to the javascript code: java.lang.System.setSecurityManager(null); I could read a jar from the filesystem without a problem.

Calling showJavaConsole is very useful for debugging:

        var jvm = Components.classes["@mozilla.org/oji/jvm-mgr;1"].getService(Components.interfaces.nsIJVMManager);
	jvm.showJavaConsole();

Here's the code I use to log exceptions. JSUtil.getStackTrace doesn't always work. I haven't figured out why, so I do it last, wrap it in a try catch, and print out my own "rough" stack trace first. (The rough list has no line numbers.) Wrap all java calls in a try catch and log the exception. Mozilla doesn't always report them and when it does it doesn't give the stack trace, and it's usually wrapped in a meaningless exception. I think the java console logs all exceptions though, so maybe this isn't necessary if you use that.

function logExc(e) {
    try {
        while(e != null) {
            debug(e);
            e = e.getCause();
        }
        debug(netscape.javascript.JSUtil.getStackTrace(e));
    } catch(exp) {
        debug("exception while logging exception");
        debug(exp);
        debug("exception being logged");
        debug(e);
    }
}


I'm still trying to figure out how to get my classes in the regular classpath so I can access them with "Packages" and not use reflection. I tried setting the classpath and it doesn't work. If you use the URLClassLoader to create an instance of a class, you can call methods on it normally. So you can say "var myclass = class.newInstance()" and then call instance methods on my class. That way you don't have to use reflection for everything.


Sometimes Javascript objects get passed to Java as JSObjects. I think it's doing that for me because of the reflection, since the URL[] works in the classloader example. JSObject is defined in $JAVA_HOME/jre/lib/plugins.jar. It's documented here: http://java.sun.com/products/plugin/1.3/docs/index.docs.html


To get the Java plugin working in Thunderbird, I had to make a ".plugins" directory in ~/.mozilla (not ~/.thunderbird), and symlink libjavaplugin_oji.so in that directory. Make sure you use one compiled with the same gcc as the thunderbird compile. It also seemed to care that it was a symlink and not a copy of the lib.so file; a copy didn't work for me until I symlinked it.