| Summary: | Classses from a wizard package loaded on empty workbench | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Pascal Rapicault <pascal> | ||||
| Component: | UI | Assignee: | 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
Pascal Rapicault
Can you remember which class(es)? 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* 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.
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. 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? 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. 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. Could you please explain what is going on? I'm just curious. Also there may be other solutions than changing references to Object. >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.
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) > 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?
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. >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.
(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. Do you know whether the verifier keeps the whole class in memory? 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. >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. >What we should think of is to turn of the bytecode verifier
I faint :-)
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... 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. |