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.
Suppose we have 2 opened projects: "Working" and "Browsing". They both represent the same system under development. "Working" contains only files currently under development, while "Browsing" contains all sources of the stable system tree. During debugging, NetBeans often opens a source (on breakpoint hit, for example), from "Browsing", even the class with the breakpoint is in "Working". I've debugged the issue using NetBeabs sources and supposedly found out that the problem is in GlobalPathRegistry.getPaths. When a debugger session is started (in my case by attaching), the debugger calls GlobalPathRegistry.getSourceRoots, which in turn calls getPaths(ClassPath.SOURCE). getPaths retrieves source paths, which are srores as an ArrayList of ClassPath (maintaning order), creates a HashSet from it and returns it. ClassPath inherits method hash() from Object. Therefore, the ordering of source paths in the set returning by getPaths depends on the object identity, i.e., on their placement in the memory. Thus, on different IDE runs the result of the source path search will be different, so sometimes debugger shows sources correctly and sometimes not. My suggestion for fixing is to use LinkedHashSet instead of HashSet (actually, getSourceRoots use LinkedHashSet for storing the source root paths).
The GlobalPathRegistry (GPR) does not cause your problem since it is used only for sources for which the classpath can not be found, it is a fall back. This should not be your case. ClassPaths are registering into GPR in undefined order, so returing them in LinkedHashSet will not help. The problems is that you have source root(s) owned by 2 or more projects which is not allowed, see issue: http://www.netbeans.org/issues/show_bug.cgi?id=54563 There is a bug in the NetBeans 4.0 that it let you to create/open such projects.
1. I do not have source root(s) owned by 2 or more projects. 2. GPR stores paths in a category (ClassPath.SOURCE, for example) using lists. Therefore, if LinkedHashSet is used, the order in GPR will be preserved, regardless whether it is defined or not. Therefore, you loose nothing using LinkedHashSet. Additionally, as I've found, the order is consitent with the order of projects in the Projects window and it is good for my configuration. 3. I just did the proposed fix locally and it seems to work. 4. The problem of showing wrong source in debugger exists regardless whether my explanation is correct or not. Therefore, I would like this issue to be handled further. If this is a result of my project configuration, I will appreciate any assistance for correcting this. I can provide my project configuration files as attachments or send them by e-mail, if necessary.
From the bug repport: "Suppose we have 2 opened projects: "Working" and "Browsing". They both represent the same system under development. "Working" contains only files currently under development." Is this true (you have sources owned by 2 projects) or not? GPR stores the ClassPaths in list but the calling of register is not ordered. It up to project type to call GPR.register. The problem of showing wrong sources is either caused by 2 projects opened with same sources, not sure about project configuration. Or debugger code does not use GPR instead of ClassPath.getClassPath (). But GPR does not imply in its contract any ordering.
From the bug repport: "Suppose we have 2 opened projects: "Working" and "Browsing". They both represent the same system under development. "Working" contains only files currently under development." This is true. But source roots of the projects are different directories. "Browsing" owns a directory where the whole developed system sits. I have only read-only permissions for it and it is used only for browsing. "Working" owns another directory, in my ownership. Generally, it is empty. If I need to change something, I check (a) file(s) or/and (a) package(s) out into the directory (of "Working"). After completing the work, I check the files in. After the system in "Browsing" is rebuilt (by someone else), I release unnecessary files from "Working". So that, the physical files and directories in "Working" are not the same as in "Browsing", but they have the same names, structure and similar contents. As for GPR, as far as I understood by debugging, it is used by debugger to establish the source search path when a debugging session is started. Maybe GPR does not define the class path ordering, but it is certainly the same for each NetBeans run. However, when the path is returned as HashSet, its ordering is different for different runs. Additionally, path ordering in the debugger is different from the ordering in GPR. I see this as a problem.
Thanks, now I understand to your projects layout. You are right that the ordering will be the same for each NB start and it will probably depend on the order you opened the projects and on the order the projects are stored in the OpenProjectList (holds at least for j2seproject type). In this case the debugger will probably use the project which was opened as the first one. But this is still not the solution, the right solution is to fix the debugger, it should know the project you are debugging and should use ClassPath.getClassPath () not the GPR, CP.getClassPath() always leads to right classpath. I will try to look into debugger.
Hanzi, can you explain why the debugger uses the GlobalPathRegistry?
No chance to fix it in 4.1.
It looks like we do not have a notion of the project which is being debugged. Therefore we use GlobalPathRegistry, which is obviously wrong. We need to know the project and retrieve the class path from it.
*** Issue 72049 has been marked as a duplicate of this issue. ***
In NetBeans 4.1 there is additional place, which causes the same problem: SourcePathProviderImpl.java, line 90, in constructor Set allSourceRoots = new HashSet();
Hmm, I understand that it is complicated to determine the right project automatically, but it would be good enough (for us), if it would use the active project.
I just want to mention that I fixed this (don't panic, locally at my place by downloading sources) in 4.0, 4.1 and 5.0 by replacing HashSet by LinkedHashSet in the problematic places. The fix took me a few minutes. But I'm really tired to do this with each netbeans release. Can you please do the same and do more complex fixup later? There are only two lines of code that should be changed. If you want, I can supply the fixed source files.
Can you attach the diff to this issue? I will try to review it and get it through the API reviews into the CVS.
Here you are. The original files are with the "orig" extension. diff ./debuggerjpda/ant/src/org/netbeans/modules/debugger/projects/SourcePathPro viderImpl.java.orig ./debuggerjpda/ant/src/org/netbeans/modules/debugger/project s/SourcePathProviderImpl.java 90c90 < Set allSourceRoots = new HashSet ( --- > Set allSourceRoots = new LinkedHashSet ( diff ./java/api/src/org/netbeans/api/java/classpath/GlobalPathRegistry.java.orig ./java/api/src/org/netbeans/api/java/classpath/GlobalPathRegistry.java 130c130 < return Collections.unmodifiableSet(new HashSet(l)); --- > return Collections.unmodifiableSet(new LinkedHashSet(l));
*** Issue 76500 has been marked as a duplicate of this issue. ***
*** Issue 54449 has been marked as a duplicate of this issue. ***
*** Issue 73031 has been marked as a duplicate of this issue. ***
Created attachment 36047 [details] Repro of this issue
When will this be fixed? This is very annoying for us, because we always have to maintain multiple versions of our application in parallel. Each version has its own NB project, but almost all sources exist in all versions/projects. So it happens very often, that NB jumps into the wrong source. Mostly, even closing the other projects before debugging is no working workaround, you also have to restart NB. IMHO, this should be a hotfix for NB 5.5. BTW: Eclipse does not have this problem.
Is it possible to get a fix for this is 5.5.1? This really is a big problem. If I'm tired of tracing through the debugger and getting the wrong files. Moreover, it creates a certain level of distrust in the IDE, that I can't rely on it to be smart enough to know which project sources I'm debugging.
Why do you change the version number? If this is a problem since 4.0, it should stay 4.0. We plan to fix this into the next trunk milestone - M9. It's too late for 5.5.1 now, we expect the release of 5.5.1 soon and only really critical fixes can go in. The reason I was reluctant to implement the proposed patch sooner was that I'm not sure that this is the correct approach to fix this problem. Projects register source paths into GlobalPathRegistry in no defined order and projects in Projects view are sorted alphabetically. Thus I do not see a way how to assure that one project will be consulted for sources sooner than another. If I understand your setup correctly, you need to search for the file in "Working" project and if it's not there then pick it up from "Browsing" project. How does the compilation and execution assures that it picks Working before Browsing? Do you have some third project, which depends on both of these in the correct order? Does Run action work properly? Please provide details about your setup. Thanks.
Why not just use the sources from the active project?
Well, I'm afraid that the active project might not be sufficient for applications composed from many projects. We, unfortunately, do not have a notion of a group of projects or "meta projects". But perhaps this could be taken as the default and allow to add source roots from the rest of the projects in Sources View. When attaching to NetBeans it would be enough to set "nbbuild" as the main project then and debugger could easily find the right sources... We'll consider this, it would be a change in the behavior, so we need to assure that it will be transparent enough to the users. We still would like to see the exact use-cases and setup that makes the problem described in this issue.
Our use-case is described in my comment above: Additional comments from tboerkel Tue Nov 28 14:01:57 +0000 2006
Aha, thanks Thomas. So it's slightly different from gennady's usecase. For you it makes sense to consider just the active (main) project when looking for sources. The others are independent (and possibly slightly different) copies, that should be ignored by the debugger. We'll try to come up with some solution for M9 milestone.
Thanks. If the source is not found in the active project, then it should look in the other projects, just like today.
As I understand, NB 6.0 M10 is feature freeze now and this bug is not fixed? Shouldn't this bug be fixed in M9?
definitely not for M9 ... Martin please reevaluate
I've reimplemented the SourcePathProviderImpl and changed the sources management a bit. That will hopefully solve this problem. Currently, when you start debugging a project inside NetBeans IDE (Debug Project), the project's boot class path and execution class path is remembered in the correct order and used for source opening in Editor. The rest of source roots that come from other opened projects is appended in alphabetically sorted order (just for convenience, there is no reliable order defined). Thus all project sources and sources of it's dependent projects should be browsable in correct order. When you attach NetBeans debugger to some remote application, then the main project (and it's execution class path) is taken in the correct order. The rest of source roots that come from other opened projects is appended in alphabetically sorted order, like in the previous case. I hope that this algorithm solves this issue. Please verify that it suits your needs and works as you expect. /shared/data/ccvs/repository/debuggerjpda/projects/src/org/netbeans/modules/debugger/jpda/projects/SourcePathProviderImpl.java,v <-- SourcePathProviderImpl.java new revision: 1.4; previous revision: 1.3
Thanks a lot for implementing this and getting it into 6.0! It works as intented. There is however a small problem. Example: I have 3 versions of an application open (3 projects with not exactly identical sources). I have the same source file from all 3 projects opened in the editor and I have set breakpoints in all 3. Now I attach the debugger and NB tries to submit all breakpoints from all 3 sources to the running program (some of them will fail, because there is no source code at that line in the running source). However, when a breakpoint is hit, it stops in the correct source (from the active project). This results in stopping at lines, where no breakpoint (in the correct source) is set. This does not happen when starting the program from within NB (not attaching). If it is an uncorrectable side effect of this fix, then I'd rather live with it instead of losing all that functionality.
Thomas, I do not think this is really a side-effect of this fix, this behavior was there before this fix as well IMHO. The problem is, that during a remote attach, all sources are selected for debugging by default and thus all breakpoints in these sources are submitted. But when there are several possible source roots available, it's true that we should probably pick just the one class for breakpoint submission, which matches the one, that gets selected when debugger stops on that breakpoint. This should be fixable...
It's hopefully fixed now. The breakpoint is submitted only when it comes from the first matched source root: /shared/data/ccvs/repository/debuggerjpda/src/org/netbeans/modules/debugger/jpda/breakpoints/Bundle.properties,v <-- Bundle.properties new revision: 1.14; previous revision: 1.13 /shared/data/ccvs/repository/debuggerjpda/src/org/netbeans/modules/debugger/jpda/breakpoints/ClassBasedBreakpoint.java,v <-- ClassBasedBreakpoint.java new revision: 1.24; previous revision: 1.23 /shared/data/ccvs/repository/debuggerjpda/src/org/netbeans/modules/debugger/jpda/breakpoints/LineBreakpointImpl.java,v <-- LineBreakpointImpl.java new revision: 1.40; previous revision: 1.39
Thanks again! It works. But I still get warnings about breakpoints from other source roots. In my opinion, it should ignore those breakpoints silently. Attaching to KAPC387:8000 LineBreakpoint P2plusServer.java : 2192 successfully submitted. Not able to submit breakpoint LineBreakpoint P2plusServer.java : 2197, reason: Breakpoint does not belong into the preferred source root 'D:\P2plus\Trunk\AppServer\P2Java'. Invalid LineBreakpoint P2plusServer.java : 2197 Not able to submit breakpoint LineBreakpoint P2plusServer.java : 2182, reason: Breakpoint does not belong into the preferred source root 'D:\P2plus\Trunk\AppServer\P2Java'. Invalid LineBreakpoint P2plusServer.java : 2182 Not able to submit breakpoint LineBreakpoint P2plusServer.java : 2177, reason: Breakpoint does not belong into the preferred source root 'D:\P2plus\Trunk\AppServer\P2Java'. Invalid LineBreakpoint P2plusServer.java : 2177 Not able to submit breakpoint LineBreakpoint P2plusServer.java : 2180, reason: Breakpoint does not belong into the preferred source root 'D:\P2plus\Trunk\AppServer\P2Java'. Invalid LineBreakpoint P2plusServer.java : 2180 User program running
Verified ... and Closing all issues resolved into NetBeans 6.7 and earlier.