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.

Bug 51005 - [40cat] SFBQ can be misleading when unrelated JARs mixed in a single library definition
Summary: [40cat] SFBQ can be misleading when unrelated JARs mixed in a single library ...
Status: CLOSED WONTFIX
Alias: None
Product: projects
Classification: Unclassified
Component: Generic Infrastructure (show other bugs)
Version: 4.x
Hardware: PC Windows XP
: P3 blocker (vote)
Assignee: Jesse Glick
URL:
Keywords:
Depends on: 51052 53368
Blocks:
  Show dependency tree
 
Reported: 2004-10-31 09:29 UTC by gugrim
Modified: 2006-03-24 09:56 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Sources screenshot (8.29 KB, image/png)
2004-11-02 18:00 UTC, gugrim
Details
Test case (29.91 KB, application/octet-stream)
2005-01-04 19:52 UTC, gugrim
Details

Note You need to log in before you can comment on or make changes to this bug.
Description gugrim 2004-10-31 09:04:48 UTC
Even more info for what it's worth:

Reverting to 200410261800 had no effect.

Removing the source zip from the list of sorces in the library did
help. Not a very nice workaround though.
Comment 1 gugrim 2004-10-31 09:29:04 UTC
[ BUILD # : 200410281800 ]
[ JDK VERSION : J2SE 1.5.0 ]

When a breakpoint is reached in a freeform
project, the source file that is opened is not
from the source directories but from a zip file in
a library, hence it is read only.

I explicitly include the project source in the
sourcepath of nbjpdastart and both the project
source and the library source is listed in the
Sources debugging window. I have tried unchecking
"Use for debugging" but it doesn't help.

This problem has not existed until recently. I
have always included all source directories and
zips in the nbjpdastart sourcepath since that has
been the only way to make breakpoints work.
Recently though it seems that the Sources window
lists a number of additional directories and zips
which correspond to my Library and Platform
definitions. I guess that the idea is that source
locations should be detected implicitly through
these definitions. Probably a good idea but in a
case where a library definition exists with a jar
that is also the output jar of my project, this
automatic detection doesn't seem to work very well.

The most important effect of this bug is that when
a breakpoint is reaches you have to "manually"
open the correct source file and locate the place
in the source if you want to fix something and/or
remove the breakpoint.
Comment 2 gugrim 2004-10-31 09:51:18 UTC
More info:
I removed the project jar file from the list of "Output JARs or
Folders..." and emptied the MDR cache in the hope that that would
break the only link I can see between my project and the library.
Strangely enough that didn't help. The Sources tab still lists the
source zip file specified in the library, with "Use for debugging" is
unchecked, and still the file is opened from the zip!
Comment 3 Jesse Glick 2004-11-01 20:46:42 UTC
You obviously have a nontrivial setup here and I can't hope to help
you without steps to reproduce.

Normally <sourcepath> is not needed for <nbjpdastart> since you can
give a <classpath> and the right sources should be inferred from that.
In any event, if you do use <sourcepath> for whatever reason and it
does something other than specify the exact source path to use for the
debugger session, please narrow it down to a small test case, which
need not involve the project system at all (just an Ant script) and
file a bug report in the 'debuggerjpda' component with steps to reproduce.

The MDR cache has nothing whatsoever to do with debugger source
finding, as far as I know.
Comment 4 gugrim 2004-11-02 17:59:43 UTC
OK, some more info:

I have removed the sourcepath tag from my nbjpdastart task. It doesn't
seem to be necessary anymore.

This is my setup:

I have one project called DOI4, which is a framework.

I have another project called Effie4, which is a general library used
by DOI4.

I have a library called DOI4. This library references the jars from
both DOI4 and Effie4. Necessary since I also have a Palette that
contain beans from DOI4 and these beans need classes in Effie4. The
library references source zips from both the DOI4 and Effie4 projects.

I also have a library called Effie4.

There is no dependency whatsoever from Effie4 to DOI4.

When I debug Effie4 the Sources window clearly shows that all source
locations referenced by the DOI4 library is included. I have checked
that if I add another location to the DOI4 library it also shows up in
the Sources window.

I have tried removing all references to Effie4 from the DOI4 library.
All remaining source locations still shows up.

I have tried removing the subproject link from DOI4 to Effie4.

I have tried dropping the palette thinking that maybe all libraries
referenced by paletted are always included. This didn't help either.

I'm starting to think that NetBeans always includes source locations
from libraries whose last letter in the name is the same as for the
project! No seriously, I haven't tried renaming it.

As I see it there are two bugs here:

The first one, which is hopefully trivial, is that even if I uncheck
"Use for debugging" in the Sources window, it is still obvioudly used.

The second one is more tricky. There must exist some obscure
relationship between libraries and projects that I just can't see. The
attached screenshot indicates that the source zips have something to
do with project DOI4 and project Effie4, but the zips are only
referenced in the DOI4 library.

I really want to do everything I can to provide you with the
information you need, but I can't think of anything more to try. Is
there some logging level that can be increased? Is there anything more
I can try?
Comment 5 gugrim 2004-11-02 18:00:36 UTC
Created attachment 18685 [details]
Sources screenshot
Comment 6 Jesse Glick 2004-11-10 23:25:22 UTC
Re. the first problem - "Use in Debugging" not working - this may be
something unrelated. I would encourage you to file a bug against the
debuggercore module, if you can supply detailed steps to reproduce
from scratch so that the debuggercore developer can try it and see for
himself.

Re. the main problem - I am still not really following what you are
doing at all. You have two projects that are mirrored in two
libraries? What are the libraries for if you already have projects? I
am assuming that the existence of the libraries is what is screwing
things up - NB sees that you are debugging some JAR, and looking for
the sources corresponding to it, it happens to find the source ZIP
first. You should be able to delete the libraries and debug the
projects directly.

Again, if you can provide steps to reproduce, this can be diagnosed,
otherwise I can't promise anything. A general description of your
setup is not enough; I am talking about a formal list of steps to
perform in a clean IDE to see the problem occur.

Currently there is not a good logging flag for this particular
subsystem, but I can add one so you can try turning it on in a dev
build. Would be a good idea anyway.
Comment 7 gugrim 2004-11-11 09:13:39 UTC
The reason that my projects are mirrored as libraries is that the
projects in question are class libraries used by several other
projects. When I work with a class library project, eg DOI4, I
naturally want to debug using the sources in that project.

However, when I work on some application project I often want that
project to use the library DOI4 instead of the project DOI4. The DOI4
library refers to the most recent build while the DOI4 project may
contain changes that may not even be compiled yet.

Anyway, using the sourcepath tag in the nbjpdastart task seems to
override solve the problem for now.

Comment 8 Jesse Glick 2004-11-11 21:29:41 UTC
I see. But then the IDE is just doing what you told it to do. If you
have a snapshot of your lib sources, and you refer to those from the
library definition (which should also be using a snapshot of the lib
binary), it should step through those. If you claim that the project's
sources correspond to the binary, then it should step through those
instead. Either tactic might be appropriate, depending on how
significant your changes are, and how likely you are to want to make
edits to lib source code while debugging.
Comment 9 gugrim 2004-11-12 11:45:06 UTC
Actually, it doesn't do what I have told it to do. I have not in any
way specified that the Effie4 project depends on or uses the Effie4
library.  Hence, the zipped sources from the Effie4 library should not
be used when debugging the Effie4 project.

To make things work I have to remove the source zip references from
the libraries and instead use sourcepath with nbjpdastart. Off corse
that means that the sources aren't available for debugging other
projects that are not freeform.
Comment 10 Jesse Glick 2004-11-12 23:44:59 UTC
Well, AFAIK the IDE just uses whatever sources you have configured for
a library/project. If you see differently, you can track it down for
yourself:

  -J-Dorg.netbeans.api.java.queries.SourceForBinaryQuery=0

(trunk builds only, starting with the next one).
Comment 11 gugrim 2004-12-02 08:08:15 UTC
I have tried the option
"-J-Dorg.netbeans.api.java.queries.SourceForBinaryQuery=0" on RC1 but
I can't see any change in behavior or any information written to the
log. The debugger still insists on opening source files from the zip
specified in a library definition. 
Comment 12 Jesse Glick 2004-12-02 16:32:00 UTC
I said *trunk* builds, i.e. of 4.1; not in any 4.0 builds.
Comment 13 gugrim 2004-12-22 09:04:22 UTC
OK, I've now tried the SourceForBinaryQuery option on 200412202121.
The following entry shows that zipped source for the DOI4 library is
found for retroweaver.jar:

[org.netbeans.api.java.queries.SourceForBinaryQuery]
SFBQ.findSourceRoots:
jar:file:/C:/Products/Tools/RetroWeaver/release/retroweaver.jar!/
[org.netbeans.api.java.queries.SourceForBinaryQuery]   got result
[AbstractFileObject@523ca2[jar:file:/C:/Projects/DOISuite4/DOI4/dist/src/doi4_src.zip!/]]
from
org.netbeans.modules.java.j2seplatform.libraries.J2SELibrarySourceForBinaryQuery@3f1224

This is in itself not surprising since retroweawer is part of the DOI4
library definition. It has to be because I have a palette defined with
beans from this library and since a library can't "depend" on another
library I must include all jars needed by the beans or the palette
won't work.

A side effect of this seems to be that in any project where
retroweaver is used (just about all my projects), the zipped DOI4
source is used by the debugger. This unfortunately includes the DOI4
project.

Although I use the <sourcepath> tag with <nbjpdastart> to specify
exactly what source roots I want when I debug it still uses source
roots guessed from the classpath. I suppose this behaviour might be
something some people like but I would prefer if it was optional. That
way I could also get rid of the JDK 1.5 sources when debugging. I
guess that they show up because my source level is 1.5, but when I
debug and run I use 1.4 since the classes are retroweaved.

Another problem is the "Go To Class" dialog. It shows two entries for
every DOI4 class, and there is no way to tell which entry is
associated with which source.

All in all, the implicit use of libraries to find source roots is
problematic with freeform project. Hopefully it will all be solved
with http://www.netbeans.org/issues/show_bug.cgi?id=47498.
Comment 14 Jesse Glick 2004-12-22 16:27:31 UTC
Re. the main problem, whatever that is now (I am not really sure):
still awaiting a minimal, self-contained test case that I can actually
try to run on my own machine to see something incorrect happen.
Include any needed files and instructions. It sounds like you have all
the information needed to reproduce this, but I don't have time to
guess what you are doing.

Probably problems are arising from your pointing to a src.zip for
something built from a project. This is very likely wrong. If you need
to use a snapshot of a library, put the binary somewhere different
from where the project builds it, and associate snapshot sources with
the snapshot binary, so that it is kept completely separate from the
project.

Re. <sourcepath> not being taken literally by <nbjpdastart> - sounds
like a bug in the debugger, which if true should please be filed in
debuggerjpda with precise steps to reproduce from scratch. AFAIK if
you specify <sourcepath> it should use exactly that path.

Re. JDK 1.5 sources - if you have a freeform project, you may specify
an explicit <classpath mode="boot">...</> for unusual cases like this
where you need to override the IDE's guess as to which JDK sources to
use based on the source level.

The "Go To Class" UI problem is filed separately: issue #49737.
Comment 15 Marian Mirilovic 2005-01-03 13:37:26 UTC
I guess this won't be fixed for NB4.0 , please evaluate again.
Comment 16 gugrim 2005-01-04 13:37:32 UTC
OK, I will try to create a test case. Until then I have a little more
info and a question:

I did as Jesse suggested and changed my library definition to point to
jars and zipped sources completely outside the project. Still, the
behavior is the same. I think I may perhaps have an idea what the
problem is:

a) The library must (AFAIK) contain the retroweawer jar, otherwise it
can't be used by palette manager. This is because beans in the library
needs retroweawer on classpath to even be instantiated.

b) The project also has retroweawer on classpath.

c) The only logged SFBQ entries that mention the zipped source are the
ones that query the source associated with retroweawer. Example:

[org.netbeans.api.java.queries.SourceForBinaryQuery]
SFBQ.findSourceRoots:
jar:file:/C:/Products/Tools/RetroWeaver/release/retroweaver.jar!/
[org.netbeans.api.java.queries.SourceForBinaryQuery]   got result
[AbstractFileObject@17d26fc[jar:file:/C:/Products/DOISuite/Effie4/effie4_src.zip!/]]
from
org.netbeans.modules.java.j2seplatform.libraries.J2SELibrarySourceForBinaryQuery@1ce67ca

d) If I remove retroweawer from the library definition the correct
source is found, i e the source inside the project.

This behavior leads me to the following theory:

If the freeform project classpath references a jar that is also part
of some library, then the sources specified for that library are used
instead of the sources in the project, even though the jar in question
(e g retroweawer) does not contain the class for which a source is
being looked up.

Also, this zipped source shows up in the debugger Sources tab, with
"Use for debugging" checked. I will file this as a nbjpdastart bug as
soon as I understand enough what is happening to be able to explain
the scenario.

A final question concerning the JDK source problem: What is <classpath
mode="boot">? Is there any info about this tag somewhere?

Comment 17 Jesse Glick 2005-01-04 16:55:48 UTC
A library is intended to really be one library. If retroweaver is used
for multiple purposes, put it in its own library. (There is no
facility for automatic inter-library dependencies currently.)

"If the freeform project classpath references a jar that is also part
of some library, then the sources specified for that library are used"
- yes. "instead of the sources in the project" - not sure what you
mean. You have retroweaver sources *in* your project?? "even though
the jar in question (e g retroweawer) does not contain the class for
which a source is being looked up." - the IDE just looks for the first
thing that claims it owns the JAR file and can provide sources for it,
which in this case is apparently a library definition.

"A final question concerning the JDK source problem: What is
<classpath mode="boot">?" - specifies what your boot classpath is;
default is to look for some registered JDK with the same source level
as you have specified, if any. "Is there any info about this tag
somewhere?" - not yet; there is no complete documentation for the
freeform project.xml syntax written yet. Pending.
Comment 18 gugrim 2005-01-04 19:11:52 UTC
Some comments and clarifications:

"If retroweaver is used for multiple purposes, put it in its own library."

-- Yes, I'd like to do that but can't because a library that contains
GUI beans and is referenced by a palette must contain retroweawer,
otherwise the beans can't be used by the GUI editor.

"If the freeform project classpath references a jar that is also part
of some library, then the sources specified for that library are used"
- yes. "instead of the sources in the project" - not sure what you
mean. You have retroweaver sources *in* your project??

-- No.

"even though the jar in question (e g retroweawer) does not contain
the class for which a source is being looked up." - the IDE just looks
for the first thing that claims it owns the JAR file and can provide
sources for it, which in this case is apparently a library definition.

-- Here I belive is the problem; Yes, the library contains the
retroweawer jar but it can't provide sources for it. It can however
provide sources for classes in another jar in the library, classes
that happen to be part of my project. My project does not in any way
reference the library but it does use the retroweawer jar which is
also used by the library. Hence, through guilt by assocation, a kind
of link exists and the sources in the library are used instead of the
project sources.

There are probably many ways in which this problem could be solved:

1) Using sourcepath if it was respected. I've just filed an issue
(http://www.netbeans.org/issues/show_bug.cgi?id=52920) concerning this.

2) Allow libraries to reference other libraries. Issue
(http://www.netbeans.org/issues/show_bug.cgi?id=51052).

3) Make the SFBQ smarter: Use only sources defined in a library if
they correspond to classes in the jar that caused the library to be
considered in the first place.

4) And obviously the solution described in issue
(http://www.netbeans.org/issues/show_bug.cgi?id=47498).

Comment 19 gugrim 2005-01-04 19:52:05 UTC
Created attachment 19473 [details]
Test case
Comment 20 gugrim 2005-01-04 19:54:24 UTC
I have now attached a test case to illustrate the problem. When the
project is built it prepares all files and echos instructions on how
to create a library with zipped sources.

Comment 21 Jesse Glick 2005-01-11 00:14:36 UTC
OK, thanks for the test case; it produces the results you say. The
basic error is including retroweaver.jar in the library. Do not do
that; put it in its own library, and use both libraries in the
classpath of anything which requires the other one. If you remove
retroweaver.jar from the library in this example, debugging works.

Re. solutions:

- Issue #47498 has little to do with this, I think.

- #3 (improving the SFBQI in j2seplatform): I don't think it will
work. The IDE would have to be open all the ZIP files in each library
and compute intersections of various fully-qualified class names to
try to guess which binary archives are supposed to match which source
archives. This could be rather time-consuming, since you have to
process each ZIP entry in turn (the query just asks for source roots
for a given binary root), and would still not be 100% accurate since a
source ZIP could have *partial* sources for a given binary JAR, etc.
Better to just have the libraries be used the way they were intended
to be used to begin with.

- #51052 (lib interdependencies) is more promising, as a convenience
so you do not need to manually add the dependent JARs.
Comment 22 Jesse Glick 2005-01-11 00:31:17 UTC
Another reason why your test case does not work: your classpath is
wrong. If in your build script, in the debug target, you replace

<pathelement location="build"/>

with

<pathelement location="dist/lib/wrongsource.jar"/>

then it works. Same if you leave the build script along but in
project.xml explain that 'build' is an output:

<compilation-unit>
    <package-root>src</package-root>
    <built-to>dist/lib/wrongsource.jar</built-to>
    <built-to>build</built-to>
    <source-level>1.5</source-level>
</compilation-unit>

The <classpath> you use in <nbjpdastart> is being used as it should,
in the order you specify, but you were not associating your project's
sources with the build directory.
Comment 23 gugrim 2005-01-11 08:52:39 UTC
Some comments:

"The basic error is including retroweaver.jar in the library. Do not
do that [snip] If you remove retroweaver.jar from the library in this
example, debugging works.

Yes, I'm aware of that. The reason it is in the library is that this
kind of setup is necessary if the library contains beans that you want
to use in a palette. Since a library can't have "required libraries"
like in JBuilder, and a palette can't reference more than one library,
such libraries need to contain dependent jars like retroweaver.

"your classpath is wrong...."

The debug target does not depend on "make", only on "compile". Hence,
the "wrongsource.jar" won't exist or be up to date so I wouldn't want
it on my classpath.

"explain that 'build' is an output"

Tried that but it didn't help.

Seems to me that the root of the problem is the lack of lib
interdependencies in combination with the palette limitation of a
single library. This forces me to include a jar like retroweaver in a
library where it shouldn't really belong.

Finally, I do not think that this issue is resolved. Perhaps there
isn't much that can or should be done within freeform but the problem
does exist for freeform projects even if they are caused by
limitations and/or bugs in other components. Since I believe that lib
interdependencies would be the cleanest way to solve this problem I
add it as "depends on" and reopen this issue a final time.
Comment 24 Jesse Glick 2005-01-13 17:31:45 UTC
Re. adding build/ as an output to project.xml - well it worked for me
when I tried it.

I was not aware that the Component Palette did not permit >1 library
to be added for a single bean; I guess that is a bug (probably never
came up before). Reporting separately. Note that it is *not* necessary
to add dependencies to a project on a bean library by means of the
Palette - this is only intended as a shortcut. The general mechanism
is to adjust your project's classpath to include whatever you will
want it to include, then add any beans that are available. See issue
#53386.
Comment 25 gugrim 2005-01-13 17:56:10 UTC
Jesse wrote:

"Note that it is *not* necessary to add dependencies to a project on a
bean library by means of the Palette - this is only intended as a
shortcut."

Sorry, I have absolutely no idea what you mean here. Please clarify.
Comment 26 Jesse Glick 2005-01-14 20:45:49 UTC
Sorry, attempting to clarify: any j2seproject has some classpath at
any given time, as does a freeform project etc. (A project can
actually have multiple classpaths for different source roots, but that
can be ignored here.) If you attempt to add a bean from the Component
Palette to a form contained in a project whose classpath can already
be used to load the bean (and all of its prerequisites), then there
should be no need for the form editor to do anything special to the
project - it can just begin using the bean class like any other code.

However, it was decided for 4.0 that many users would not realize they
needed to configure their classpath to include everything needed for a
bean ahead of time, or would not want to be bothered to do it, so as a
convenience we added a special facility whereby a project could
advertise to the form editor that it had a way of adding a subproject,
JAR, or library to its classpath. Now if the bean on the palette is
configured to come from a particular subprj/JAR/lib, and the classpath
for the form does not already contain it, the form editor can quietly
add that classpath item for you (rather than requiring you to do it
yourself in the project properties dialog), if you are using a project
that supports this (currently means just j2seproject, though it would
be possible to extend that to freeform projects I think).

My point was this feature is only intended as a convenience, not the
only way to add a bean - you ought to be able to configure your
project's classpath ahead of time to contain whatever it will need,
then add any beans which can be found in that classpath. This ought to
serve as a workaround in case a bean requires more than one library to
compile and/or run, and the form editor does not yet permit you to
associate all these libraries with the bean.

If there is some problem making such a workaround really work, please
file it with details in the 'form' component - I don't know that much
about it as I have rarely used beans other than those from Swing.
Comment 27 gugrim 2005-01-15 08:52:12 UTC
Thanks Jesse, interesting info. I have now created a library
definition that is used only to define the palette. This library has
no sources. That way SFBQ won't get confused by the fact that the jars
needed for the beans exists in several libraries. Not a very
farfetched solution once you undestand how SFBQ works!

Also, the boot classpath setting worked perfectly. I can now step into
JDK1.4 source even though my sourcelevel is 1.5, which is necessary
for retroweaved projects. Thanks again.
Comment 28 Jesse Glick 2005-01-17 20:25:00 UTC
Probably you can use the "Add from JAR" rather than "Add from Library"
in the Palette Manager, but I wouldn't know much about it.
Comment 29 gugrim 2005-01-18 17:12:22 UTC
No, you can only use "Add from JAR" if the jar contains all classes
needed by the beans. The DOI4 beans need the support library Effie4 as
well as Retroweaver.
Comment 30 Jesse Glick 2005-01-22 21:44:40 UTC
I'm aware that the JAR with the bean doesn't contain its dependencies,
but assuming that all the JARs are already in the project's classpath
so that the actual compilation and running of the project will work,
what actually happens when you add the bean from that JAR? Does the
Palette Manager let you do it? Are there errors later when using the bean?
Comment 31 gugrim 2005-01-23 11:22:10 UTC
Jesse wrote:

"..what actually happens when you add the bean from that JAR? Does the
Palette Manager let you do it?"

Yes it does but it doesn't show any icons.

"Are there errors later when using the bean?"

No everything works fine except that the palette pane in the form
editor doesn't show any icons. The property pane clearly finds and
uses BeanInfo but apparently not the palette pane.

BTW, I was a little too quick saying that the boot classpath setting
works perfectly. If I use a JDK 1.4 bootclasspath I can debug and step
into JDK 1.4 classes but then code completion and parsing during
editing also uses JDK 1.4 even though the source level is 1.5. When
editing I want the editor to behave as if I'm using 1.5 but when I
debug I want the debugger to use 1.4 since my classes are by then
"retroweaved". Naturally I must be careful not to use 1.5 only API 
but that is a comparably small price to pay.

I honestly don't expect NetBeans to support this special situation and
I solve it by having the bootclasspath setting within comments so I
can fairly easily switch it in when I really need it. Issue 52920
(exclusive sourcepath) should fix this but it isn't a big deal really. 
Comment 32 Jesse Glick 2005-01-23 19:40:04 UTC
Re. no icons: ah. Bummer. Probably the form editor tries to load the
bean classes in-VM from what it thinks is the classpath, for
development-time purposes. So that would be something that has to be
fixed in form.

Re. "If I use a JDK 1.4 bootclasspath I can debug and step
into JDK 1.4 classes but then code completion and parsing during
editing also uses JDK 1.4 even though the source level is 1.5." - not
quite sure what you mean here. There are two independent things you
can configure: the source level (means whether generics are enabled
for code completion, asserts are treated as keywords, the -source
option passed to the internal background parser, etc.), and the
bootclasspath (where to look for JDK sources). You *should* be able to
use JDK 1.5 source level with a JDK 1.4 bootclasspath, if that is what
your project.xml requests - though obviously this is a very special
situation and you are probably the first to try it.
Comment 33 gugrim 2005-01-24 07:28:19 UTC
Re "You *should* be able to use JDK 1.5 source level with a JDK 1.4
bootclasspath":

I believe NetBeans behaves as correctly as can be expected. The editor
accepts 1.5 syntax but it won't accept that e g java.util.List takes a
type parameter, and I can't blame it. The best way to work with a
RetroWeaved project is probably to leave the bootclasspath alone and
then override the debugging sourcepath when (and if) that becomes
possible.
Comment 34 Marian Mirilovic 2005-07-12 10:02:23 UTC
closed