vossad01
vossad01

Reputation: 11958

Why does rearranging imports cause compilation to fail?

Why may re-arranging Java imports cause the code to no longer compile?

I thought that the order of Java imports was not significant to the the semantics of the code making it a safe operation. Editors make it really easy to organize/optimize/rearrange Java import statements and some style checking/analysis tools will enforce an order. I am not successfully finding posts online mentioning the dangers of rearranging imports. However, I have now encountered a case where rearranging the imports causes the code to break.

The following code will not compile saying it cannot find the symbol Retention:

package foo;
import foo.BadImportsTest.TestOptions.Option;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.junit.Assert;
import org.junit.Test;

public final class BadImportsTest {
  @Retention(RetentionPolicy.RUNTIME)
  public @interface TestOptions {
    enum Option {
      BAR,
      BAZ,
    }
  }

  @Test
  public void DoTest() {
    Assert.assertNotEquals(Option.BAR, Option.BAZ);
  }
}

However, in its original order with the first import (foo.BadImportsTest.TestOptions.Option) last, it does compile.

I tried checking the spec. It seems like this is a Single-Type-Import Declaration but my reading of section 7.5.1 does is not explaining the above behavior. I am importing a nested type in the current file, however, it that would cause an issue with anything it would seem it should error on finding Option since:

If the type imported by the single-type-import declaration is declared in the compilation unit that contains the import declaration, the import declaration is ignored.

I tested compilation both via Maven and IntelliJ IDEA, targeting Java 8 in all cases.

I did find Order of imports seems to matter for compilation to succeed? but that points to a compiler bug that would seem not to apply because it concerned static imports and I am not using static imports. Additionally, it is marked as fixed in Java 8 and I am using Java 8.

Upvotes: 3

Views: 202

Answers (2)

sashwat
sashwat

Reputation: 647

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6391197

The below code still gives me an error.

package test;

import static test.Outer.Inner.CONST;
import java.util.Iterator;

class Outer {
  interface Inner extends Iterator {
    static String CONST = "CONST";
  }
}

The bug still exists in java 8, atleast in my compiler version : javac 1.8.0_121.

Java 8 relevant bug: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8148472

So this is a bug, go for the workaround.

Upvotes: 2

Alex Reed
Alex Reed

Reputation: 119

My guess is that it cannot find the retention import because the import 'foo.BadImportsTest.TestOptions.Option;' is importing something from the same class it is in. By putting that import first, you cause the importing process to fail before anything can import. By putting it last, its failure cannot prevent any other imports from failing because they have already been inputted, thus not producing the error you receive if you put it first.

Upvotes: 0

Related Questions