This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 421375 - Repeated ClassNotFoundExceptions in AdaptExpression cause UI freezes
Summary: Repeated ClassNotFoundExceptions in AdaptExpression cause UI freezes
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Runtime (show other bugs)
Version: 4.3.1   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 4.4 M4   Edit
Assignee: Paul Webster CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 421866
  Show dependency tree
 
Reported: 2013-11-08 16:27 EST by Sergey Prigogin CLA
Modified: 2013-12-11 13:23 EST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sergey Prigogin CLA 2013-11-08 16:27:48 EST
Here is a typical call stack of a freeze:

"main" prio=10 tid=0x00007fd06c009000 nid=0x7684 runnable [0x00007fd072b91000]
   java.lang.Thread.State: RUNNABLE
	at (C/C++) 0x00007fd0740f87e2 (Unknown Source)
	at (C/C++) 0x00007fd07338bab8 (Unknown Source)
	at (C/C++) 0x00007fd07347b5d4 (Unknown Source)
	at (C/C++) 0x00007fd0731eff30 (Unknown Source)
	at (C/C++) 0x00007fd0743b3df1 (Unknown Source)
	at java.lang.Throwable.fillInStackTrace(Native Method)
	at java.lang.Throwable.fillInStackTrace(Throwable.java:782)
	- locked <0x00000007e5a867b0> (a java.lang.ClassNotFoundException)
	at java.lang.Throwable.<init>(Throwable.java:287)
	at java.lang.Exception.<init>(Exception.java:84)
	at java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:75)
	at java.lang.ClassNotFoundException.<init>(ClassNotFoundException.java:82)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl(ClasspathManager.java:506)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:465)
	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:395)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:464)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:360)
	at (C/C++) 0x00007fd069000438 (Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:266)
	at org.eclipse.core.internal.expressions.AdaptExpression.evaluate(AdaptExpression.java:85)
	at org.eclipse.core.internal.expressions.CompositeExpression.evaluateOr(CompositeExpression.java:68)
	at org.eclipse.core.internal.expressions.OrExpression.evaluate(OrExpression.java:21)
	at org.eclipse.ui.internal.navigator.NavigatorPlugin$Evaluator.run(NavigatorPlugin.java:245)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.navigator.CustomAndExpression.evaluate(CustomAndExpression.java:71)
	at org.eclipse.ui.internal.navigator.NavigatorPlugin$Evaluator.run(NavigatorPlugin.java:245)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.navigator.NavigatorPlugin.safeEvaluate(NavigatorPlugin.java:260)
	at org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptor.isPossibleChild(NavigatorContentDescriptor.java:454)
	at org.eclipse.ui.internal.navigator.NavigatorContentService.findOverridingLabelExtensions(NavigatorContentService.java:477)
	at org.eclipse.ui.internal.navigator.NavigatorContentService.findPossibleLabelExtensions(NavigatorContentService.java:466)
	at org.eclipse.ui.internal.navigator.NavigatorContentServiceLabelProvider.getStyledText(NavigatorContentServiceLabelProvider.java:145)
	at org.eclipse.ui.internal.navigator.NavigatorDecoratingLabelProvider$StyledLabelProviderAdapter.getStyledText(NavigatorDecoratingLabelProvider.java:67)
	at org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.getStyledText(DelegatingStyledCellLabelProvider.java:195)
	at org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider.getStyledText(DecoratingStyledCellLabelProvider.java:192)
	at org.eclipse.ui.internal.navigator.NavigatorDecoratingLabelProvider.getText(NavigatorDecoratingLabelProvider.java:221)
	at org.eclipse.cdt.ui.CElementSorter.compareWithLabelProvider(CElementSorter.java:416)
	at org.eclipse.cdt.ui.CElementSorter.compare(CElementSorter.java:310)
	at org.eclipse.ui.navigator.CommonViewerSorter.compare(CommonViewerSorter.java:140)
	at org.eclipse.jface.viewers.TreePathViewerSorter$1.compare(TreePathViewerSorter.java:105)
	at java.util.TimSort.binarySort(TimSort.java:265)
	at java.util.TimSort.sort(TimSort.java:208)
	at java.util.TimSort.sort(TimSort.java:173)
	at java.util.Arrays.sort(Arrays.java:659)
	at org.eclipse.jface.viewers.TreePathViewerSorter.sort(TreePathViewerSorter.java:103)
	at org.eclipse.jface.viewers.AbstractTreeViewer.getSortedChildren(AbstractTreeViewer.java:639)
	at org.eclipse.jface.viewers.AbstractTreeViewer.updateChildren(AbstractTreeViewer.java:2643)
	at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefreshStruct(AbstractTreeViewer.java:1923)
	at org.eclipse.jface.viewers.TreeViewer.internalRefreshStruct(TreeViewer.java:721)
	at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefreshStruct(AbstractTreeViewer.java:1930)
	at org.eclipse.jface.viewers.TreeViewer.internalRefreshStruct(TreeViewer.java:721)
	at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefreshStruct(AbstractTreeViewer.java:1930)
	at org.eclipse.jface.viewers.TreeViewer.internalRefreshStruct(TreeViewer.java:721)
	at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh(AbstractTreeViewer.java:1898)
	at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh(AbstractTreeViewer.java:1855)
	at org.eclipse.ui.navigator.CommonViewer.internalRefresh(CommonViewer.java:561)
	at org.eclipse.jface.viewers.StructuredViewer$8.run(StructuredViewer.java:1535)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1443)
	at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:403)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1404)
	at org.eclipse.jface.viewers.StructuredViewer.refresh(StructuredViewer.java:1533)
	at org.eclipse.jface.viewers.ColumnViewer.refresh(ColumnViewer.java:555)
	at org.eclipse.ui.navigator.CommonViewer.refresh(CommonViewer.java:350)
	at org.eclipse.ui.navigator.CommonViewer.refresh(CommonViewer.java:510)
	at org.eclipse.cdt.ui.CElementContentProvider$RefreshElement.refresh(CElementContentProvider.java:369)
	at org.eclipse.cdt.ui.CElementContentProvider$1.run(CElementContentProvider.java:448)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:136)
	- locked <0x00000007c7071368> (a org.eclipse.swt.widgets.RunnableLock)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3717)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3366)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1113)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:997)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:138)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:610)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:567)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181)
	at (C/C++) 0x00007fd069000438 (Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1426)
Comment 1 Paul Webster CLA 2013-11-08 16:31:38 EST
Could you please attach the log?  It looks like a plugin is there and one of its dependencies is missing.

PW
Comment 2 Sergey Prigogin CLA 2013-11-08 16:41:42 EST
(In reply to Paul Webster from comment #1)

The exception happens without a missing dependency. AdaptExpression calls Class.forName(fTypeName, false, var.getClass().getClassLoader()). Whenever the class named by fTypeName belongs to a plugin that is not dependency of the plugin where var resides, ClassNotFoundException is thrown. Please notice that the the class loader used is not the classloader of the plugin that provided the expression, but the class loader of the plugin that created the object being adapted.
Comment 3 Paul Webster CLA 2013-11-08 16:51:41 EST
(In reply to Sergey Prigogin from comment #2)
> (In reply to Paul Webster from comment #1)
> 
> The exception happens without a missing dependency. AdaptExpression calls
> Class.forName(fTypeName, false, var.getClass().getClassLoader()). Whenever
> the class named by fTypeName belongs to a plugin that is not dependency of
> the plugin where var resides, ClassNotFoundException is thrown. Please
> notice that the the class loader used is not the classloader of the plugin
> that provided the expression, but the class loader of the plugin that
> created the object being adapted.

Ah, OK.  It's a fallback for objects that are IAdaptable (and have no factories registered).  It was added to solve the case that an object implements IAdaptable and so hard codes what it can return.

It was done as part of Bug 211288

PW
Comment 4 Sergey Prigogin CLA 2013-11-08 17:01:44 EST
(In reply to Paul Webster from comment #3)

Yup. I'm going to fix it by using a cache of class names that could not be loaded.
Comment 5 Sergey Prigogin CLA 2013-11-08 19:32:32 EST
The proposed fix is in Gerrit at https://git.eclipse.org/r/#/c/18242/.
Comment 6 Dani Megert CLA 2013-11-12 02:14:12 EST
Would be nice to have a test case or steps that allow to show the improved performance/responsiveness.
Comment 7 Sergey Prigogin CLA 2013-11-12 12:17:32 EST
(In reply to Dani Megert from comment #6)
> Would be nice to have a test case or steps that allow to show the improved
> performance/responsiveness.

Demonstating difference in resposiveness would require a realistic Eclipse installation with many plugins that contribute their expressions and a large project since the time spent in expression evaluation is proportional to the number of nodes in Project Explorer or a similar view. Both these conditions are hard to model in a test.
Comment 8 Sergey Prigogin CLA 2013-11-15 15:06:22 EST
Uploaded new proposed fix (https://git.eclipse.org/r/#/c/18242/) with loadClass method moved to Expressions.
Comment 10 Paul Webster CLA 2013-12-11 13:23:00 EST
In 4.4.0.I20131209-2000

PW