Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 191725

Summary: Classses from a wizard package loaded on empty workbench
Product: [Eclipse Project] JDT Reporter: Pascal Rapicault <pascal>
Component: UIAssignee: JDT-UI-Inbox <jdt-ui-inbox>
Status: RESOLVED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: daniel_megert, darin.eclipse, jeffmcaffer, martinae, ob1.eclipse
Version: 3.3   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
JDT UI classes none

Description Pascal Rapicault CLA 2007-06-08 11:26:49 EDT
Eclipse 3.3
While investigating problems with the permgen space, we have noticed that on an
empty workspace, the activation of the jdt.ui plug-in loaded classes from a package called wizard, which was pretty intriguing since no wizard had been opened. Could you please investigate what is going on?
Are those classes supposed to be loaded?
Note that using the core tools you can find why a class is being activated (http://www.eclipse.org/eclipse/platform-core/downloads.html)
Comment 1 Dani Megert CLA 2007-06-08 15:13:09 EDT
Can you remember which class(es)?
Comment 2 Pascal Rapicault CLA 2007-06-08 15:24:42 EDT
These ones:

org.eclipse.jdt.internal.ui.wizards.NewElementWizard*
org.eclipse.jdt.internal.ui.wizards.NewTypeDropDownAction*
org.eclipse.jdt.internal.ui.wizards.NewWizardMessages*
org.eclipse.jdt.internal.ui.wizards.OpenJavaProjectWizardToolbarAction*
org.eclipse.jdt.internal.ui.wizards.OpenPackageWizardToolbarAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathWizard*
org.eclipse.jdt.internal.ui.wizards.buildpaths.ClasspathContainerWizard*
org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement*
org.eclipse.jdt.internal.ui.wizards.buildpaths.EditFilterWizard*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.AddArchiveToBuildpathAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.AddFolderToBuildpathAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.AddFolderToBuildpathAction$1*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.AddLibraryToBuildpathAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.AddLibraryToBuildpathAction$1*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.AddSelectedLibraryToBuildpathAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.BuildpathModifierAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.ConfigureBuildPathAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.CreateLinkedSourceFolderAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.CreateSourceFolderAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.EditFilterAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.EditOutputFolderAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.EditOutputFolderAction$1*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.ExcludeFromBuildpathAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.ExcludeFromBuildpathAction$1*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.GenerateBuildPathActionGroup*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.GenerateBuildPathActionGroup$NoActionAvailable*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.GenerateBuildPathActionGroup$UpdateJarFileAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.IncludeToBuildpathAction*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.IncludeToBuildpathAction$1*
org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.RemoveFromBuildpathAction*
Comment 3 Pascal Rapicault CLA 2007-06-08 15:32:15 EDT
Created attachment 70734 [details]
JDT UI classes

In fact, as a congratulation gift for the RC4 release ;-), here is a list of the classes that are loaded while opening an empty workspace on the java perspective.

You will notice the presence of the javaeditor package... a lot of actions (maybe a problem in UI) a few search and dialogs classes. All that where the only things I have done is closed the welcome editor.
Comment 4 Dani Megert CLA 2007-06-11 07:05:46 EDT
I have no clue what your tool does but when I put a class load breakpoint into e.g. NewElementWizard or JavaEditor those clases are NOT loaded.
Comment 5 Dani Megert CLA 2007-06-12 03:21:23 EDT
Pascal, can you provide more info? Did you eventually try this with an Europa instead of plain Eclipse SDK drop? Are you 100% sure that there wasn't a second window that had an editor open?
Comment 6 Pascal Rapicault CLA 2007-06-12 10:55:27 EDT
The tool monitors classloading activity. The class may be loaded but not initialized which is why you may not hit the breakpoint.
If you don't want to use / trust the tool you could put a breakpoint in BundleLoader#findClassInternal().

Note that the same information has been observed with tools provided by the JRE.

I was running a pure SDK.
Comment 7 Dani Megert CLA 2007-06-12 11:08:31 EDT
OK, this most likely means that the classes are used by the verifier. I don't think we will refactor our code or replace a concrete type with Object to fix that.
Comment 8 Pascal Rapicault CLA 2007-06-12 11:35:47 EDT
Could you please explain what is going on? I'm just curious.
Also there may be other solutions than changing references to Object.
Comment 9 Dani Megert CLA 2007-06-12 12:03:10 EDT
>Could you please explain what is going on? I'm just curious.
I suspect that the code in BundleLoader#findClassInternal() and the tool gets triggered by something else than the Debug's Class Load breakpoint which isn't triggered in this scenario. Darin, can you explain? Is it maybe rather a clas INIT breakpoint?

JavaPlugin is the point where we get lots of our special singleton instances from (e.g. document provider). Of course they are coded in a on-demand way but before the class loader loads the JavaPlugin.class it loads many other types in order to verify JavaPlugin.class. Same happens for other types.
Comment 10 Darin Wright CLA 2007-06-12 12:50:19 EDT
The "class load breakpoint" is triggered when the class is prepared. I found that the breakponits were hit, for example, when I opened the "New Java Project" wizard - so whatever the classloader is doing is not "preparing" the class as defined by the Java VM Specification

(http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html#71421)
Comment 11 Dani Megert CLA 2007-06-12 13:25:44 EDT
> for example, when I opened the "New Java Project" wizard -
Yes, that's also what I saw. It seems that BundleLoader#findClassInternal() and the tool that Pascal uses listens for some other event. Pascal, can you clarify on this and explian what exactly makes them think the class is loaded?
Comment 12 Pascal Rapicault CLA 2007-06-12 15:32:50 EDT
The class is being loaded because the classloader is being asked to load it and loads it!
By setting a breakpoint in the BundleLoader#findClassInternal(), I have been able to notice that the loading of this class is triggered instantiation of the GenerateBuildPathActionGroup in the PackageExplorerActionGroup.
Comment 13 Dani Megert CLA 2007-06-13 05:23:06 EDT
>The class is being loaded because the classloader is being asked to load it and
>loads it!
Looks like there are different definitions of load/loaded as obviously the class loader "loads" the class (confirmed via -verbose:class) but does not prepare it and not trigger the "Class Load" breakpoint. I also verified that the cause for this is the bytecode verifier as starting with -noverify no longer loads all those classes.

Does one of you know which of the two "load" events actually loads the full class into the permGen memory.

Darin, can you implement/offer a class load Breakpoint which is the same as when Java logs it using -verbose:class (in addition to the PREPARE based one)? If not, we should probably rename the Class Load breakpoint.

Again, I think reworking our code to prevent class loading by the verifier is not something we should do. This will lead to clumsy ugly code.
Comment 14 Darin Wright CLA 2007-06-13 10:30:59 EDT
(In reply to comment #13)
> Darin, can you implement/offer a class load Breakpoint which is the same as
> when Java logs it using -verbose:class (in addition to the PREPARE based one)?
> If not, we should probably rename the Class Load breakpoint.

JDI only support a class prepare event. We name if the "load" breakpoint to be more user friendly - but "prepare" would be more precise.
Comment 15 Dani Megert CLA 2007-06-13 11:19:35 EDT
Do you know whether the verifier keeps the whole class in memory?
Comment 16 Martin Aeschlimann CLA 2007-06-14 05:08:01 EDT
The verifier has the unpleasant property to load (or better say 'prepare') all classes involved in all assignments or casts in a class.
In our example, the Package explorer creates its context menu actions.
The EditFilterAction (used to set includion/exclsion filters) has a method that returns a 'EditFilterWizard'.
To verify the correct assignment of the return value to a variable, the byte code verifier loads that class and its subclasses, including NewElementWizard.
So this is just the byte code verifier, no instance of a NewElementWizard is created.


To do something against that is quite difficult. It leads to quite ugly code, where you either return elements as Objects, or separate code into static helpers. Secondly, it depends a lot on the verifier, what is checked and how. Once you broke up your code, it is very difficult to maintain the separation as its very easy to add a reference again.
So I don't think this is the right approach, as this mostly makes the code hard to manage.

What we should think of is to turn of the bytecode verifier, but pre-verify our classes. As all our classes are in signed JAR's now, we can guarantee that our files are not manipulated.

Comment 17 Dani Megert CLA 2007-06-14 05:14:21 EDT
>Secondly, it depends a lot on the verifier, what is checked and how.
Right - IBM and Sun VMs for example don't load the same (amount of) classes when verifying the code.

>What we should think of is to turn of the bytecode verifier
The problem with that is that AFAIK the option to disable the verifier is a non-standard option.
Comment 18 Pascal Rapicault CLA 2007-06-14 07:12:27 EDT
>What we should think of is to turn of the bytecode verifier
  I faint :-)
Comment 19 Jeff McAffer CLA 2007-06-15 08:07:08 EDT
Actually the real problem is that the option is global.  If we could turn off the verifier for particular classloaders, then perhaps we could not verify signed bundles (or some such).  But there would still be issues if, for example, bundle A required classes from bundle B and A was signed/trusted and B was not...
Comment 20 Martin Aeschlimann CLA 2007-07-03 05:21:54 EDT
No action planed on our side. As said in comment 16, working around a verifier leads to strange code (returning Object instead of a type or separating functionality in static helpers), that is hard to establish and to manage.
If somebody uses the the Java tooling, he will eventually lead most of the classes anyway. I a user doesn't use JDT, we should make sure the JDT plugins are never loaded.