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 125582 - Problems with classpath when working with external roots
Summary: Problems with classpath when working with external roots
Status: RESOLVED FIXED
Alias: None
Product: projects
Classification: Unclassified
Component: Generic Infrastructure (show other bugs)
Version: 6.x
Hardware: All All
: P2 blocker (vote)
Assignee: Milos Kleint
URL:
Keywords:
: 132664 (view as bug list)
Depends on:
Blocks:
 
Reported: 2008-01-18 17:16 UTC by Michel Graciano
Modified: 2008-07-15 13:45 UTC (History)
4 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Free form example project; (1.15 MB, application/x-compressed)
2008-01-21 12:07 UTC, Michel Graciano
Details
Potential solution based on keeping the external roots info in preferences (3.20 KB, patch)
2008-06-20 15:12 UTC, Jaroslav Tulach
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michel Graciano 2008-01-18 17:16:46 UTC
When the IDE is opened with a form already opened from previous session, the IDE show a warning that the super class was
not found. I have a class which extends the JXTaskPane from SwingX project, and the warning is that JXTaskPane can't be
found. So, I wait a minute, until IDE finish to scan my project classpath, and reload the form, and everything looks
works again. I think the form loader is loading form before classpath loader finish.

Regards.
Comment 1 Jan Stola 2008-01-21 10:03:15 UTC
I am sorry, I am not able to reproduce this issue. What build do you use? What JDK?
Comment 2 Michel Graciano 2008-01-21 12:01:04 UTC
Product Version: NetBeans IDE Dev (Build 200801180000)
Java: 1.6.0_03; Java HotSpot(TM) Client VM 1.6.0_03-b05
System: Linux version 2.6.22-14-generic running on i386; ISO-8859-1; pt_BR (nb)
Userdir: /home/michel/.netbeans/dev

So, FYI, to reproduce this I will attach a free form project. This just occur when the project and source folders are
different. Just unpack the zip and try to open the project. Steps to reproduce:
1-Open the project, and the class NewTask;
2-Close the IDE;
3-Open the IDE again so, a exception should be throw.

Regards.
Comment 3 Michel Graciano 2008-01-21 12:07:51 UTC
Created attachment 55311 [details]
Free form example project;
Comment 4 Jan Stola 2008-01-21 13:10:36 UTC
> 1-Open the project, and the class NewTask;

I opened the project, built it, but I wasn't able to open NewTask. There must be something odd in project's 
configuration.
Comment 5 Michel Graciano 2008-01-21 14:12:54 UTC
Any exception? I think it should be some problems on classpath.
BTW, the problem just happen when I have a nbproject outside project files (sources and build files) folder, as in the
attachment structure. When I use "normal" projects, everything works fine.
Comment 6 Jan Stola 2008-01-21 16:25:37 UTC
Finally, I was able to reproduce this issue. I took the source files from the attached project and created a new Java 
Project with Existing Sources. I left the sources outside the project's tree (as suggested).

The debugger shows that ClassPath.getClassPath(formFile,ClassPath.EXECUTE) returns null because FileOwnerQuery in 
ProjectClassPathProvider.findClassPath() returns null for the form file.

Reassigning to java module for evaluation.
Comment 7 Michel Graciano 2008-01-21 17:07:50 UTC
FYI, I have problems for Free Form projects too.

Regards.
Comment 8 Tomas Zezula 2008-01-21 18:18:07 UTC
From the report it seems that java/classpath is wrong category, project/code seems to be the right one. I will try the
attached project and reassign.
Comment 9 Tomas Zezula 2008-01-21 19:01:30 UTC
I am not able to reproduce it, however thanks to jstola evaluation its quite clear what happened.
>The debugger shows that ClassPath.getClassPath(formFile,ClassPath.EXECUTE) returns null because FileOwnerQuery in 
>ProjectClassPathProvider.findClassPath() returns null for the form file.
The project type didn't register the external source roots yet (the FileOwnerQuery doesn't know that the source root is
owned by the project), so there is no classpath for it.
Probably related to lazy projects.
Comment 10 Tomas Pavek 2008-01-22 17:57:49 UTC
Yes, this a consequence of issue 108120 which postpones project opening after startup. If the form is loaded during 
startup, the project is not opened yet, so the external source root can't be matched with the project and the classpath 
is not determined.

This happens only when three conditions are met (which is IMHO a rather rare case):
- the form is under an external source root (out of project dir)
- the form uses a custom class (i.e. not from JDK)
- the form is selected in editor when the IDE is shut down

The workaround is easy - reload the form after the IDE starts. Note it is not needed to wait for the scan to finish - 
just the projects needs to open on background after start - this happens relatively quickly (and it triggers the 
scanning).

Ideally this should be fixed in projects infrastructure - e.g. by saving external roots for the projects during 
shutdown so FileOwnerQuery can work even without the project opened.
Comment 11 Jan Lahoda 2008-05-02 20:12:11 UTC
The FileEncodingQuery is, IMO, also affected by the lazy project loading (for projects with external source roots).
Given that incorrect results of FileEncodingQuery can lead into a data loss (if the user does not notice the file was
loaded with an incorrect encoding, modifies it and saves it, the resulting file may be very broken), I do not think this
qualifies as P5.

I was able to make the IDE load the file with incorrect encoding:
-created a new J2SE project, changed its encoding to a non-default value (my system encoding is UTF-8, I used
windows-1250 for the project).
-created an external source root, added it into the project, created a new Java class, typed a few Czech letters into a
comment.
-disabled the Welcome screen, made the file in the external source root active and restarted the IDE. I have added
Thread.sleep(5000); at the beginning of the J2SEProject's constructor to simulate slow project loading.
-the file was loaded incorrectly (did not contain the proper Czech letters). After I have closed and reopened the file,
it was loaded correctly.
Comment 12 Jaroslav Tulach 2008-06-20 15:10:27 UTC
Imho, the problem is there even in 6.0. It is just made more visible in 6.1:
- open project with external root
- open a file in the external root
- close the project
- do File/Open Recent File to open the file that just has been closed
- maybe the problem is there already, otherwise restart to get it
As such I think the flaw is in project infrastructure itself, it has nothing to do with me or mine changes.
Comment 13 Jaroslav Tulach 2008-06-20 15:12:48 UTC
Created attachment 63170 [details]
Potential solution based on keeping the external roots info in preferences
Comment 14 Jesse Glick 2008-06-20 15:55:30 UTC
I think Yarda's patch has the right general idea. As a matter of API discipline, this does not match the documented
contract of FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT. Fortunately, the algorithm is intentionally replaceable - IIRC,
there was discussion of making external roots persistent even for 4.0, but it was dropped (perhaps because settings
storage was harder at the time). Adding a new algorithm (EXTERNAL_ALGORITHM_PERSISTENT) and using it in various project
types (via SourcesHelper.registerExternalRoots) would be more correct.

There may be unpleasant consequences of a change like this. Generally speaking, marking of external source roots is a
tricky thing, especially since we do not yet do the marking consistently at project open time, rather at project load
time (filed separately). There can be problems if two projects try to claim the same root, etc. I think the patch (with
corrected API usage) would be a net improvement, however.
Comment 15 Milos Kleint 2008-07-01 14:59:30 UTC
Since the project lazy loading in a hack in general, I think we can solve the problems it introduces with hacks as well.
Instead of permanently remembering all the external source root we can, just remember the ones that are knows at
shutdown and reload them on startup (and then discard the persisted state). That seems like the least harm solution to
the problem to me.

jglick: I'm not convinced the EXTERNAL_ALGORITHM_PERSISTENT is a good idea. I can't think of any solid reasons, why, but
it feels like trouble.

Comment 16 Jesse Glick 2008-07-01 18:23:42 UTC
"Instead of permanently remembering all the external source root we can, just remember the ones that are known at
shutdown and reload them on startup (and then discard the persisted state)." - may make sense. I'm not sure it's
necessarily harmless, though: if there is some "bad" registration, not only will restarting the IDE not clear it, but
restarting again and again will not clear it either - unless you only persist the ones that were explicitly registered
during this session, and not the ones you remembered from the last session.
Comment 17 Milos Kleint 2008-07-02 15:38:44 UTC
fixed
http://hg.netbeans.org/main/rev/68aba8984cd4


works for a fully qualified super class, if the super class is in the same package and not fully qualified, it will
still fail. However that's probably has different cause-> different bug.
Comment 18 Quality Engineering 2008-07-03 04:31:51 UTC
Integrated into 'main-golden', available in NB_Trunk_Production #296 build
Changeset: http://hg.netbeans.org/main/rev/68aba8984cd4
User: Milos Kleint <mkleint@netbeans.org>
Log: #125582 serialize the known external roots on shutdown and use the deserialized info on startup when the project opened routine was not yet run and the external sources are not marked yet officially.
Comment 19 Quality Engineering 2008-07-03 15:39:11 UTC
Integrated into 'main-golden', available in NB_Trunk_Production #297 build
Changeset: http://hg.netbeans.org/main/rev/2ddb65148459
User: Milos Kleint <mkleint@netbeans.org>
Log: #125582 use logger instead of error manager
Comment 20 Jan Lahoda 2008-07-15 12:16:18 UTC
*** Issue 132664 has been marked as a duplicate of this issue. ***
Comment 21 Jaroslav Tulach 2008-07-15 13:38:35 UTC
Why cannot the SimpleFileOwnerQueryImplementation deserialize its data when first invoked instead in own 
ModuleInstall? Can you please defer the deserialization till it is really needed?
Comment 22 Milos Kleint 2008-07-15 13:45:26 UTC
jardo, it's used almost instantly after startup the project system starts loading. I know you are hunting your startup
numbers, but please not at my expense. it'd rather have the code simple and maintainable rather then optimized for an
arbitrary startup metric.

Please perform some hard measurements regarding the impact of current solution before reopening the issue, thanks.