2

I'm compiling this very simple and naive Java code with Eclipse, and javac:

package anypackagename;

public class Foo {

    public static void bar(Class<?> cls) {
        while (cls != null) {
            final Class<?>[] interfaces = cls.getInterfaces();

            // ... 

            cls = cls.getSuperclass();
        }
    }
}

The issue is that I'm getting different bytecode with different tools.

Compiled with Eclipse I got:

public static void bar(java.lang.Class<?>);
    Code:
       0: goto          13
       3: aload_0
       4: invokevirtual #18                 // Method java/lang/Class.getInterfaces:()[Ljava/lang/Class;
       7: astore_1
       8: aload_0
       9: invokevirtual #24                 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
      12: astore_0
      13: aload_0
      14: ifnonnull     3
      17: return
    LineNumberTable:
      line 6: 0
      line 7: 3
      line 11: 8
      line 6: 13
      line 13: 17

however, compiled with javac I got:

 public static void bar(java.lang.Class<?>);
    Code:
       0: aload_0
       1: ifnull        17
       4: aload_0
       5: invokevirtual #2                  // Method java/lang/Class.getInterfaces:()[Ljava/lang/Class;
       8: astore_1
       9: aload_0
      10: invokevirtual #3                  // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
      13: astore_0
      14: goto          0
      17: return
    LineNumberTable:
      line 6: 0
      line 7: 4
      line 11: 9
      line 12: 14
      line 13: 17

apparently "Eclipse has implemented its own compiler called as Eclipse Compiler for Java (ECJ)." ( What is the difference between javac and the Eclipse compiler? )... what I would like to know is if there is any option to use in Eclipse to have the same bytecode produced by javac.

Community
  • 1
  • 1
josecampos
  • 851
  • 1
  • 8
  • 25
  • 1
    The 2 byte codes are effectively the same.. So, it doesn't matter which compiler you use :) – TheLostMind Jul 31 '15 at 16:33
  • 1
    Sure! Use ant or maven to build. Also, check that you're using the same compiler level in both. – Elliott Frisch Jul 31 '15 at 16:33
  • Mmm @Jon: Not sure if this is duplicated with http://stackoverflow.com/questions/14186091/how-to-configure-eclipse-to-compile-using-oracle-javac-1-7-0-09 : In that question there is actually no answer telling how to configure Eclipse to do so – Javier Jul 31 '15 at 17:20
  • 1
    @Javier: Hmm. It's a duplicate *question*, but I agree that it doesn't have a positive answer. (There are other questions too - I suspect they're the same.) I doubt that there *is* any way of just getting JDT to use javac... – Jon Skeet Jul 31 '15 at 17:22
  • @JonSkeet, it might help to distinguish two **roles** of the compiler: several options exist for using `javac` in Eclipse for the task of **creating .class files** (via maven, ant, etc... links exist in the other thread). OTOH, all **UI features of the IDE** which need parsed and semantically analysed sources are tightly and inevitably coupled to ECJ. Yes, Eclipse is able to _build_ your project using any tool of your liking. No, Eclipse is not able to swap the compiler used for quick fixes, refactoring, navigation, code completion, you name it. – Stephan Herrmann Aug 01 '15 at 19:33
  • On a different notion, it's interesting to see that typically this question is asked by people who are simply surprised about some small difference. Typically, once people understand the situation, they no longer feel the urge to switch to javac in the first place. That's why some answers contain a grain of "but why would you do it? You will sacrifice the seamless integration in the IDE for what benefit?" – Stephan Herrmann Aug 01 '15 at 19:40

1 Answers1

0

Does it matter which bytecode you use? Honestly, probably not. They'll do the same thing at a relatively similar speed.

Now, if you do want to use the javac compiler instead of ECJ, you can set that in the runtime options, and your code will simply be compiled with javac. There's no reason for ECJ to be able to do this, nor is there any way it ever could since the commercial version of javac (I believe) is closed-source.

Just switch to javac in the runtime options if it matters.

nameless912
  • 367
  • 1
  • 12
  • Can you please be more specific about where in Preferences or Project properties can you do that? – Javier Jul 31 '15 at 17:22
  • yes, it matters. imagine that you're using a coverage tool like Eclemma ( http://www.eclemma.org/ ). because bytecode compiled with Eclipse doesn't include line 12, Eclemma or any other tool that relies on bytecode, will not be able to assign coverage to that particular line. – josecampos Jul 31 '15 at 21:06
  • @josecampos Obviously, eclemma is well integrated with Eclipse and should be well aware of the code patterns generated by ECJ. Now, why would you be interested in the code coverage of the `}`? There is nothing to execute here. It has the exact same coverage as the statement before. The `goto` in javac's output is purely artificial, just like the initial `goto` in ecj's output. Regarding the observable behavior both compilers are identical (modulo bugs). The behaviour you want to track is not observable by the Java semantics. – Stephan Herrmann Aug 01 '15 at 19:51