Path: csiph.com!news.swapon.de!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Steven Simpson Newsgroups: comp.lang.java.programmer Subject: Re: Is it necessary the source file should be at the same location with the class file? Date: Mon, 25 Jul 2016 21:21:54 +0100 Organization: A noiseless patient Spider Lines: 185 Message-ID: <209i6d-u46.ln1@s.simpson148.btinternet.com> References: <8bnf6d-sua.ln1@s.simpson148.btinternet.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Info: mx02.eternal-september.org; posting-host="9fcb3f23b3bcb8532517da33c152ddd9"; logging-data="25247"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18Ez9hhm9HCEwjHtZc3jxLZ1cT4rFageO8=" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 In-Reply-To: X-Mozilla-News-Host: news://localhost Cancel-Lock: sha1:Mt+sCyq0H9xrE4eV64wDr0/SAOA= Xref: csiph.com comp.lang.java.programmer:35136 On 24/07/16 23:06, Arne Vajhøj wrote: > On 7/24/2016 5:08 PM, Steven Simpson wrote: >> With the output directory in the classpath, doesn't it mean that javac >> will attempt a kind of incremental build? And doesn't it then miss some >> not particularly extraordinary cases (inlined constants; return types), >> leading to broken builds? > The problem you mention is real and need to be handled. There are > ways to do that via various build scripts from OS shell to ant to > newer build frameworks. I was not convinced that Ant would be enough, as the task behaves largely as [javac -classpath out -d out], comparing timestamps of corresponding .java and .class files, so it's exposed to the same problems. Combining with should do better, but it looked like it would still miss inlined constants, so I tried it out: mkdir src cat > build.xml < EOF cat > src/A.java < src/B.java <":()V #2 = Methodref #19.#20 // C.test:()Ljava/lang/String; #3 = Class #21 // D #4 = Fieldref #22.#23 // java/lang/System.out:Ljava/io/PrintStream; #5 = Class #24 // java/lang/StringBuilder #6 = Methodref #5.#18 // java/lang/StringBuilder."":()V #7 = String #25 // CONSTANT = #8 = Methodref #5.#26 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #9 = Methodref #5.#27 // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; #10 = Methodref #5.#28 // java/lang/StringBuilder.toString:()Ljava/lang/String; #11 = Methodref #29.#30 // java/io/PrintStream.println:(Ljava/lang/String;)V #12 = Class #31 // B #13 = Class #32 // java/lang/Object #14 = Utf8 #15 = Utf8 ()V #16 = Utf8 Code #17 = Utf8 test #18 = NameAndType #14:#15 // "":()V #19 = Class #33 // C #20 = NameAndType #17:#34 // test:()Ljava/lang/String; #21 = Utf8 D #22 = Class #35 // java/lang/System #23 = NameAndType #36:#37 // out:Ljava/io/PrintStream; #24 = Utf8 java/lang/StringBuilder #25 = Utf8 CONSTANT = #26 = NameAndType #38:#39 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #27 = NameAndType #38:#40 // append:(I)Ljava/lang/StringBuilder; #28 = NameAndType #41:#34 // toString:()Ljava/lang/String; #29 = Class #42 // java/io/PrintStream #30 = NameAndType #43:#44 // println:(Ljava/lang/String;)V #31 = Utf8 B #32 = Utf8 java/lang/Object #33 = Utf8 C #34 = Utf8 ()Ljava/lang/String; #35 = Utf8 java/lang/System #36 = Utf8 out #37 = Utf8 Ljava/io/PrintStream; #38 = Utf8 append #39 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #40 = Utf8 (I)Ljava/lang/StringBuilder; #41 = Utf8 toString #42 = Utf8 java/io/PrintStream #43 = Utf8 println #44 = Utf8 (Ljava/lang/String;)V { public B(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: return public static void test(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=1, args_size=0 0: invokestatic #2 // Method C.test:()Ljava/lang/String; 3: pop 4: bipush 10 6: istore_0 7: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 10: new #5 // class java/lang/StringBuilder 13: dup 14: invokespecial #6 // Method java/lang/StringBuilder."":()V 17: ldc #7 // String CONSTANT = 19: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: iload_0 23: invokevirtual #9 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 26: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 29: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 32: return } Entry #3 in the constant pool refers to class D, even though no other part of the class file uses it. That's evidently enough to get to force recompilation of B. Bytecode from javac 7 doesn't include that reference. So Ant will handle the two mentioned cases if used with and javac from JDK8. -- ss at comp dot lancs dot ac dot uk