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 115918

Summary: F9 does not compile dependent files
Product: java Reporter: mclaassen <mclaassen>
Component: ProjectAssignee: Jesse Glick <jglick>
Status: VERIFIED FIXED    
Severity: blocker CC: anebuzelsky
Priority: P2    
Version: 6.x   
Hardware: All   
OS: All   
Issue Type: DEFECT Exception Reporter:
Bug Depends on:    
Bug Blocks: 49026, 85707, 116230    
Attachments: Sample NB 6 project as discussed in issue description

Description mclaassen 2007-09-18 21:30:53 UTC
In previous versions of Netbeans (5.5.1 and earlier), compile single on a file would do what javac would do:
* compile <MyFile>
* compile any classes that <MyFile> depends on that are out of date

The compile-single in NB 6 does not do this.  The current behavior is quite frustrating and makes compile single on a
file pretty useless.  I can't think of any benefit to having it implemented as it is currently, so I hope it can still
be fixed.

BTW, I am currently using build 200709180000

Create a file called MyInterface:
public interface MyInterface {
		public void foo();
}
Create a file called MyClass:
public class MyClass implements MyInterface {
		public void foo() {
		}
}
Scenario 1:
-----------
Do a compile single on MyClass.
* You will get a "cannot find symbol" error
symbol: class MyInterface

Scenario 2:
-----------
Do a compile single on MyInterace
Do a compile single on MyClass
* Now it will work since the MyInterface .class file was created before the compile-single on MyClass.  I believe that
the first scenario should have worked.
Comment 1 mclaassen 2007-09-18 21:33:19 UTC
Created attachment 49024 [details]
Sample NB 6 project as discussed in issue description
Comment 2 Jesse Glick 2007-09-19 19:43:16 UTC
As designed; see issue #85707. F9 now behaves very simply to invoke javac on the selected file only. This gives you more
control over what gets compiled. If you want to compile dependent classes as well, simply build the whole project.
Comment 3 mclaassen 2007-09-19 21:04:25 UTC
I think this is a poor decision.  Building the whole project with the <depends> and the jar file creation just takes way
too long on a big project.  

In the past few days I have been very frustrated with compile-single.  I will go in and change an interface, change the
class that implements it, and then hit compile-single on the class.  IN NB 5.5.1 this would have done exactly what I
would have expected and wanted.  In NB 6, it doesn't work. 

In the past few days, the current implementation of compile-single has been useful to me only about 5% of the time.

I have used this feature in NB for years and years and have NEVER wanted it to be any different.  Furthermore, I am
uncertain if the "additional control over what gets compiled" you mention has any non-theoretical value.

Case 1:
-------
Let's say MyFile has dependancies on other classes that are compiled, but are out-of-date yet still compatible with MyFile

In this case, there is no real different to a user.  I cannot think of a situation where the compilation of a dependant
compatible file has any deleterious effects.  Compiling the out-of-date files could even be helpful if the run target
was overridden to not do a build/jar first.


Case 2:
-------
Let's say MyFile implements MyInterface and a method is added to MyInterface.   Let's also say that MyInterface has not
yet been compiled with the new changes.
Now say an orthogonal change to MyFile and then do a compile-single.

MyFile will compile correctly, but against the old MyInterface definition.  However, since MyFile does not implement the
changed MyInterface, subsequent builds will necessarily fail

Case 3:
-------
Let's say MyFile implements MyInterface and a method is changed in MyInterface and a corresponding change is also made
in MyFile.
Now do a compile-single on MyFile.

MyFile will not compile correctly because it does not match the old interface definition

Conclusion: 
Case 1 is not definitive.  There is not down-side to compiling the dependancies, and only a minor up-side.
Case 2 is confusing and goes against user expectations
Case 3 makes compile-single unhelpful.  One could go and compile MyInterface first and then do MyFile, but that seems
bothersome.

In the 3 cases I could think up, there are only disadvantages to the current implementation and only advantages to old one.

In fact, I believe that one could make a compelling argument that, because of the Case 2, the feature should be removed
entirely to avoid confusion.  However, I think a much better solution would be to change compile-single to work as it
has in all previous versions.

I implore you to re-examine the decision not to fix this.  I love Netbeans and the great additions in 6.0, but please
don't cripple something I use every day.  If you are still not conviced, please reply with your reasoning and hopefully
we can reach a consensus.

Thank you,
Mark
Comment 4 Jesse Glick 2007-09-19 22:16:16 UTC
What I said before was right in a way - F9 just sends a single file to javac (it does not use <depend>, that is issue
#85707); and unlike in previous releases it also deletes any matching .class file for that source, just in case (ensures
that you are really compiling the file).

The critical difference from 5.5 is that to support issue #49026, sourcepath="" was added to the <javac> macro for the
'compile' target... and 'compile-single' picked up this setting as well. Strictly speaking, that is correct, since in
the case you have

class A {}
class B {A a;}

where A.java is excluded from the project but B.java is included, and you press F9 on B.java, the build would fail - you
have to decide to either include A.java, or not refer to it.

However it seems the desirability of making F9 operate transitively outweighs this point of correctness, especially as
F11 will continue to reject B.java in the above scenario, so you would probably find the problem quickly enough anyway.
Therefore readding sourcepath just to compile-single (and compile-test-single), which should make behavior more similar
to that in previous releases for this action.

Checking in test/unit/src/org/netbeans/modules/java/j2seproject/BuildImplTest.java;
/shared/data/ccvs/repository/java/j2seproject/test/unit/src/org/netbeans/modules/java/j2seproject/BuildImplTest.java,v 
<--  BuildImplTest.java
new revision: 1.15; previous revision: 1.14
done
Checking in src/org/netbeans/modules/java/j2seproject/resources/build-impl.xsl;
/shared/data/ccvs/repository/java/j2seproject/src/org/netbeans/modules/java/j2seproject/resources/build-impl.xsl,v  <--
 build-impl.xsl
new revision: 1.100; previous revision: 1.99
done
Comment 5 Jesse Glick 2007-09-19 22:42:30 UTC
As an aside, the usage of sourcepath="" for #49026 is essentially a hack to work around the limited interface offered by
command-line javac. If the project type were not using Ant, it would be possible to use JSR 199 to issue warnings or
errors when attempting to refer to excluded classes, while still supporting transitive compilation of dependencies.
Comment 6 mclaassen 2007-09-20 16:02:37 UTC
Thank you!

I love it when these mechanisms just work.
Comment 7 mclaassen 2007-09-20 16:04:35 UTC
I was so excited that it was working, I forgot to mention that I did verify the change in the daily of 20070920000.
Comment 8 Jesse Glick 2007-09-20 16:20:31 UTC
OK, thanks. BTW you can mark issues VERIFIED if you are the reporter and you can confirm that a fix worked.