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

Bug 406346

Summary: IllegalArgumentException: "Attempted to beginRule..." inside IJavaProject.isOnClasspath()
Product: [Eclipse Project] JDT Reporter: Brian Vosburgh <brian.vosburgh>
Component: CoreAssignee: JDT-Core-Inbox <jdt-core-inbox>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: jarthana
Version: 4.3   
Target Milestone: ---   
Hardware: Macintosh   
OS: Mac OS X   
Whiteboard: stalebug
Attachments:
Description Flags
stack trace for IllegalArgumentException none

Description Brian Vosburgh CLA 2013-04-23 12:23:49 EDT
Created attachment 230034 [details]
stack trace for IllegalArgumentException

During workspace start-up we (Dali) initialize a set of "JPA projects". That is, we build a JPA project for every project in the workspace with a JPA facet (facets are used by the WTP Faceted Project nature). Until recently, we would lock the workspace root while we built our JPA projects (via a scheduling rule for the initialization job). This would cause a performance/usability problem if any project was particularly large - the user would not be able to modify and save any files in unrelated projects until the Dali initialization job was finished (see bug 379755).

In an attempt to reduce the impact of Dali's initialization, we changed our code to schedule multiple jobs, one for each project in the workspace and each locking only that project while building the corresponding JPA project. In the course of building a JPA project, we ask the corresponding Java project whether a particular resource is on the Java project's classpath (IJavaProject.isOnClasspath(IResource)). Sometimes, although not often, this can result in an IllegalArgumentException

java.lang.IllegalArgumentException: Attempted to beginRule: P/Foo, does not match outer scope rule: P/Bar

because the method JavaProject.isOnClasspath(IResource) can trigger a workspace-wide initialization (JavaModelManager.initializeAllContainers(...)). This will trigger a Project.touch(...) on every project in the workspace and each touch will try to acquire a lock on the corresponding project. This is not allowed within the scope of the Dali lock of some other, unrelated project. See the attached stack trace.

My questions:
Isn't it a bit unexpected that the method IJavaProject.isOnClasspath(IResource)can require a lock on every project in the workspace? Is that the expected behavior? If so, the method needs a bit better documentation. Also, if this is expected behavior, how can we work around it, presumably by triggering the mass initialization outside our initialization jobs?
Comment 1 Jay Arthanareeswaran CLA 2013-04-24 00:41:50 EDT
IJavaProject#isOnClasspath() doesn't say anything about resource locking and I agree, the documentation could use some additional information.

The workaround you mentioned sounds good - please refer to JavaCore#initializeAfterLoad() for more details.
Comment 2 Eclipse Genie CLA 2019-03-07 01:39:10 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.