6

Here is my class:

package pepelu;

import pepelu.ImportTest.InnerClass.InnerEnum;
import javax.annotation.Resource;

public class ImportTest {
    @Resource
    public static class InnerClass {
        public enum InnerEnum {
            A
        }
    }

    public static void main(String[] args) {
        System.out.println(InnerEnum.A);
    }
}

When I use maven to build, it will give a compilation error:

mvn clean compile

[ERROR] /Users/finup/Desktop/a/importtest/src/main/java/pepelu/ImportTest.java:[8,6] cannot find symbol

After changing the import order to:

import javax.annotation.Resource;
import pepelu.ImportTest.InnerClass.InnerEnum;

I got a successful maven build.

I searched for documents, but cannot find an explain for this.

Could anyone please explain how import works in this case?

GhostCat
  • 137,827
  • 25
  • 176
  • 248
Pepe Lu
  • 63
  • 3
  • 1
    Thats bcoz u have used @Resource before than Enum – Adya Aug 16 '18 at 09:18
  • 1
    Why do you have `import pepelu.ImportTest.InnerClass.InnerEnum;` in the first place?.. :S I can't think of any scenario where you'd want to import itself. It almost feels like a paradox, similar as irl putting a box inside itself.. – Kevin Cruijssen Aug 16 '18 at 09:23
  • 1
    I was reading code of [Redisson](https://github.com/redisson/redisson/blob/master/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java) and find it import like this. I wonder how it can work in Redisson, so I write this test, and find myself cannot make it. @GhostCat – Pepe Lu Aug 16 '18 at 09:34
  • See also https://stackoverflow.com/questions/40440653/why-do-i-get-different-compilation-result-depending-on-java-imports-and-static-i/67901069#67901069 describing a similar problem and refering to this known bug-report https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6391197 – Simeon Jun 09 '21 at 10:52

1 Answers1

5

I guess the reason is a "circular" dependency: you have some element X that you import within the same file/class where you are defining it.

Meaning:

import pepelu.ImportTest.InnerClass.InnerEnum;

actually refers to code following in the very same file:

public static class InnerClass {
    public enum InnerEnum {

This means: for the compiler, in order to process that import, it has to look into the body of the class in the same file.

It seems that javac does that "immediately". Meaning: it starts reading import statements, and importing from the same class makes it "suspend" looking at imports, but checking out the following class definition.

And guess what: that class definition makes use of another import. In order to "process" the definition of that enum, the compiler needs to understand where/what that @Resource annotation is about. But it doesn't know the annotation yet (because the compiler didn't see the import, yet).

When you change the order, the compiler understands that @Resource usage in the class definition.

And of course: the real answer is not to reorder imports. The real answer is to not import something from the class that is following after the import statements. There is absolutely no point in doing so.

Edit, given the comment by the OP about how this can work in Redisson: honestly, I don't know. It might depend on how exactly that class is compiled. Maybe such code works with newer (or older) versions of javac, maybe this works with specific versions of the eclipse or intellij or xyz compiler.

Meaning: I gave you an explanation why you are running into this problem. That doesn't mean that any compiler must necessarily run into the same problem.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • but how [Redisson](https://github.com/redisson/redisson/blob/master/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java) did this? @Nikita Koksharov . In this Redission file, he import org.redisson.RedissonLiveObjectServiceTest.TestEnum.MyEnum; before import org.redisson.api.annotation.REntity. Will different compiler have different behavior? – Pepe Lu Aug 16 '18 at 09:47
  • 1
    @GohstCat thanks for you explain and I will accept this. Anyway, I will try to contact developer of redisson to find my answer – Pepe Lu Aug 17 '18 at 07:42
  • Sure. Feel free to add that information later on here. As obscure it looks, it is still interesting! – GhostCat Aug 17 '18 at 07:53