This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 152226 - Exposing packages from groovy-all.jar as public packages
Summary: Exposing packages from groovy-all.jar as public packages
Status: NEW
Alias: None
Product: groovy
Classification: Unclassified
Component: Code (show other bugs)
Version: 6.x
Hardware: All All
: P2 blocker with 1 vote (vote)
Assignee: Martin Janicek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-11-03 19:09 UTC by akochnev
Modified: 2013-09-04 09:01 UTC (History)
0 users

See Also:
Issue Type: ENHANCEMENT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description akochnev 2008-11-03 19:09:30 UTC
I am trying to create a "NetBeans Monkey" type of module (e.g. equivalent to Eclipse Monkey, or Grease Monkey), where
the IDE would be able to run user supplied scripts inside the IDE (or for that matter run a Groovy console "inside" the
IDE and inspect the internals of the IDE interactively.

So far, I have a very simple example that I have had some success with :

1. I create a "Wrapper Module" around the groovy-all.jar and expose the groovy jar's public packages.
2. I create a "Groovy IDE Console" module, that has a very simple action with the following content :

public void performAction() {
        Binding bind = new Binding();
        groovy.ui.Console console = new groovy.ui.Console(this.getClass().getClassLoader(),bind);
        console.run();                
}

Basically, the idea is that this fires up a Groovy console bubble that has access to all APIs within NetBeans that the
"Groovy IDE Console" module had declared dependencies on.

So far so good, I was able to fire up the console, and do things like (taken from
http://bits.netbeans.org/dev/javadoc/org-openide-dialogs/org/openide/NotifyDescriptor.html) inside the console:
NotifyDescriptor d =
     new NotifyDescriptor.Message("Hello...", NotifyDescriptor.INFORMATION_MESSAGE);
 DialogDisplayer.getDefault().notify(d);

And I get the expected dialog.

However, when I run this statement I get some warnings similar to this one :
"WARNING [org.netbeans.ProxyClassLoader]: Will not load class groovy.lang.Closure arbitrarily from one of
org.netbeans.StandardModule$OneModuleClassLoader@db248c[org.netbeans.modules.groovy.editor] and
org.netbeans.StandardModule$OneModuleClassLoader@1e2f6b0[groovyall.lib]; see http://wiki.netbeans.org/DevFaqModuleCCE"

Now, I looked at the FAQ and it makes a lot of sense : if both classes are available from two different classloaders, it
just refuses to load either one. Now, initially when I had exposed the classes from the groovy jar as public, I was
actually getting some nasty ClassCastExceptions in the IDE (as described in the FAQ). Then, I made the classes from my
wrapper module (around groovy-all.jar) only available to the "friend module" - my "Groovy IDE Console" module. When I
did that the IDE exceptions stopped (as expected, now the IDE module were only seeing the groovy classes from the Groovy
Editor module (which has a private copy of groovy-all.jar).

Now, when I try to run a different statement , e.g. :
org.openide.windows.IOProvider.getDefault().getIO("MyTab", false)

I get the same error in the netbeans error log (WARNING [org.netbeans.ProxyClassLoader]: Will not load class
groovy.lang.Closure arbitrarily from one of org.netbeans.StandardModule$OneModuleClassLoader@1767553[groovyall.lib] and
org.netbeans.StandardModule$OneModuleClassLoader@1afe460[org.netbeans.modules.groovy.editor]; see
http://wiki.netbeans.org/DevFaqModuleCCE), and the call above fails with the following message:
Exception thrown: java.lang.IllegalArgumentException: argument type mismatch
java.lang.IllegalArgumentException: argument type mismatch
        at Script0.run(Script0:1)

So, it's pretty clear that my one line script as the groovy.lang.Closure class is not available in the console, and I'd
imagine quite a number of things wouldn't work as expected.

I tried a variation of the proposed solution on the FAQ, but it still doesn't work.

So, going back to the original request. My idea is that if the groovy-all.jar classes (e.g. groovy.lang.*, whatever
else) are exposed as public packages in a Library Wrapper module (instead of just keeping the jar inside Groovy Editor),
then I would be able to declare a dependency on the said module, and not have to provide my own library wrapper module
is causing these clashes.

I also have the feeling that there has to be an alternative solution to this problem. At a higher level, the problem is
in a collision between duplicate classes that are provided by two different modules (which should be isolated from each
other by the module system). I also understand that it is very likely that the problem is due to the way the Groovy
classloader might be work, as it's not written w/ the expectation of running inside the IDE. 

Anyway, if there is a cleaner solution than the one I request, I'd be very interested in learning what the recommended
approach is.
Comment 1 Petr Hejl 2008-11-19 15:47:51 UTC
I'll look into this however right now I can't promise you anything. It is very risky to provide groovy-all.jar as public
API (due to incompatibilities) withot deep analysis of consequences.