4

I am facing a conflict with class and package names that have same name under different source. In a nutshell, the directory structure looks somewhat like this:

src/test/java
    com.service.helper
        Constants.java

src/intTest/java
    com.service.helper
        Constants.java
    com.service.utility
        SomethingTest.java

The few constant strings defined in both Constants.java are same and few are exclusive to these classes. Now I have a SomethingTest.java file under src/intTest/java which should utilize Constants.java defined under src/intTest/java.

However, it seems it is using Constants.java file which is defined under src/test/java package. Thus, I am not able to use constant string defined in Constants.java under src/intTest/java file.

Could anyone please give any clarity why is it so? Can I really access Constants.java defined under src/intTest/java, without changing package structure of current file names?

Appreciate the help. Thanks.

Kurshit
  • 143
  • 2
  • 15
  • 1
    From java's point of view: same package-name + same class-name = same class. I don't know if you could somehow solve your problem using your own custom class-loader, but I'd rather not go down this route but use package+class-names as they are intended to be used. – piet.t Mar 06 '18 at 08:19
  • Try using static imports, access the variable directly com.service.helper.Constants.PI; – xMilos Mar 06 '18 at 08:29
  • The imports used are already static. The problem still persists. I just wanted to ensure that there is not any way that I can access such files without renaming them. Yeah, that's it I guess ! Thanks a ton! – Kurshit Mar 06 '18 at 10:55

2 Answers2

4

The identity of a Java class is its "absolute" name, as in x.y.z.SomeClass. When you have two classes that have absolute identical package and class names, then "java" isn't able to distinguish them.

In other words: this is bad practice. You really want to avoid such situations. The solution is not to work around "my tool is complaining" but organize your source code in ways that are more in line with "standard java conventions".

In other words: the best thing to do would be to either rename some of the packages, or make sure to have unique class names.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • It does appear few flaws in naming convention for classes in my project. As suggested, I changed the class name and things worked. – Kurshit Mar 06 '18 at 10:51
2

You have 2 choices here:

  1. rename Constants to IntConstants (to be unique)
  2. (recommended) put intTest (I guess it's integration test) to it's own package.

Choice 2 is recommended as integration tests does not need to be in the same package as tested class, as it just tests public API of you application and do not need access to any package-scope variables. If it's otherwise in your case, please consider refactoring your code to align it with good practice, and do not expose internal state outside. Putting integration tests to different package helps to keep this practice.

Maciej
  • 1,954
  • 10
  • 14
  • Hey! I finally renamed the classes. Also, for the point, the intTest does hold all integration test cases and refers few constant strings defined in Constants.java file. The actual classes which are under test are in different source folder - src/java/main. The inputs were quite helpful. Kudos! – Kurshit Mar 06 '18 at 10:53
  • 2
    yea I can see it's standard folders maven structure, but there is a difference between folder structure & package structure. What I meant is that everything in folder `src/intTest/java` could be moved to it's own package also like `com.service.integration.helper` instead of reusing `com.service.helper` package. – Maciej Mar 06 '18 at 11:20
  • 1
    Oh, in that way !?! Yeah, that makes sense :) – Kurshit Mar 06 '18 at 11:45