Package Declaration Does Not Match Source Directory
ID |
java.invalid_package_declaration |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Code Smell |
Language |
Java |
Tags |
code-style, naming |
Description
Reports a package declaration that the file’s own directory path does not end with. A file with no package declaration, or sitting directly at the scanned root with no directory in front of the package, is left alone.
A .java file under a resource or fixture tree is also left alone: below a resources directory (src/main/resources, src/test/resources, src/it/resources), below a top-level test-resources, or below src/<set>/files or src/<set>/fixtures. Such a file is test input, not source — nothing compiles it, and a deliberately "wrong" package is often the point of the fixture.
The check deliberately does not try to identify the source root. Whatever precedes the package on disk is the source root, and a project may declare any number of them: src/main/java and src/test/java are only the Maven defaults, Gradle projects add src/it/java, src/testFixtures/java and src/jmh/java, Android product flavours add one root per flavour (src/playstore/java, src/androidTest/java, src/debug/java), and generated sources land under names like src/main/java-templates. Requiring the directory to end with the declared package is exactly the property javac needs, and it holds for every source set without configuration.
Rationale
The compiler, the IDE and every build tool assume a class’s fully-qualified name maps directly onto its file’s path under the source root. When the declared package and the on-disk directory disagree, "find usages", refactoring, and the generated .class file layout all stop matching what a developer sees in the file tree — confusing at best, and a source of hard-to-explain build or classpath errors at worst.
// file: src/main/java/com/example/wrong/Order.java
package com.example.right;
public class Order {
}
// file: src/it/java/org/sonar/db/DbTester.java -- OK, a non-default source set is still a source set
package org.sonar.db;
public class DbTester {
}
// file: sonar-duplications/src/test/files/java/MessageResources.java -- OK, fixture input, never compiled
package org.apache.struts.util;
public class MessageResources {
}