Java error - bad source file: file does not contain class x . Please remove or make sure it appears
Asked Answered
S

8

17

Recently started studying Java for an exam.

While learning packages, tried this and got an error message. What I did was


//Creating class A (Within package the package: com.test.helpers)
    
package com.test.helpers;
public class A {
    public void sayHello(){
        System.out.println("Hello World");
    }
}

//And then the class App utilising the class A
    
import com.test.helpers.*;

public class App{
  public static void main(String args[]){
    A a = new A();
    a.sayHello();
  }
}

I had both of these files in a directory called 'JavaTest' (on Windows 7), and first compiled the A.java using the command javac -d . A.java

And then, while attempting to compile App.java, I got the following error message:


App.java:5: error: cannot access A
                A a = new A();
                ^
bad source file: .\A.java
  file does not contain class A
  Please remove or make sure it appears in the correct subdirectory of the source path.
1 error

However, the problem seems to resolve in two ways,

  1. Deleting the Source file A.java
  2. Changing the import statement from import com.test.helpers.*; to import com.test.helpers.A in the file App.java.

I'd be highly grateful if you can explain what happens here. Or I might be making a goofy human mistake or a syntax error.

Here's the link to the source files

Schmitt answered 18/7, 2014 at 18:3 Comment(5)
class App is in the default package, right ?Observation
Yes, I believe so. The directory structure is this (After compling A.java) Desktop>JavaTest -com>test>helpers>A.class -A.java -App.java Thank you for taking time to have a loook.Schmitt
emmh, i cant see the directory structure, but class A should be in the path JavaTest\com\test\helpers\A.java , is it ?Observation
Sorry, the first comment doesn't clearly show the class structure. The source files (A.java and App.java) was inside a folder called "JavaTest". After A.Java was complied, it's class file appeared inside JavaTest>com>test>helpers. The error appears when tried to compile App.java It becomes ok if the A.java is deleted or the import statement in App.java changed, replacing the asterisk with the explicit class name, i.e A. Btw, thanks for taking time to have a look.Schmitt
By the way, if you'd like, here's the download link to the project: link Thanks.Schmitt
B
10

Hi the problem here is that the JVM confuses the class file due to the ambiguous class file name in both the directory (the JavaTest as well as the com.test.helpers directory).

when you do javac -d . A.java the compiler makes a class file in the directory com.test.helpers and now it confuses it with the sourcefile there in JavaTest

  1. Deleting the Source file A.java

When you delete the source file A.java from JavaTest, JVM knows now that the class file in com.test.... is to be used, ambiguity goes away.

  1. Changing the import statement from 'import com.test.helpers.*;' to 'import com.test.helpers.A' in the file, 'App.java'.

Here you are specifying which particular file to use in your class implementation that is you are telling the compiler to use the file A.java from com.test... and not from JavaTest package

Now, the solution for this ambiguity to not ever be a problem for you, you must import the specific files with import statement i.e. import com.test.helpers.A; or if you want to do import com.test.helpers.*; then you must specifically use com.test.helpers.A in place of A everywhere in your current class implementation to tell the compiler not to confuse it with the source at JavaTest

I know it's a lot late for this particular answer, but I wanted to share my views for the upcoming readers, if it could help them in any way, it would be great. Thanks!

Burned answered 24/9, 2017 at 11:33 Comment(0)
P
4

move the A.java under folder JavaTest to com/test/helpers. the error you are seeing is for the compiler complaining that A.java is in a folder that does not match its package declaration. Remember, you cannot access A from App without A being in a package.

from under src driectory run the following command to compile your classes

src> javac ./*.java ./com/test/helpers/*.java

then from under src folder

src>java App

that should run your program.

Petronel answered 18/7, 2014 at 18:51 Comment(1)
Thank you. The main thing I'm wondering is why the program worked with A.java source file in the wrong folder, but with import statement using the class name explicitly, instead of wildcard * ? Any explanation highly appreciated.Schmitt
O
2

the file A.java should be in the path JavaTest\com\test\helpers\A.java

and don't forget to compile it like this: javac -d . com\test\helpers\A.java

Observation answered 18/7, 2014 at 18:17 Comment(3)
Thank you, that works perfectly. And do you have any idea why the error never appears when the import statement in the App.java changed from codeimport com.test.helpers.*;code to codeimport com.test.helpers.A;code ?Schmitt
honestly i dont know, but my guess is it has something to do with the internals of the classloader. as the A.class ended up in the right path it had no trouble finding it, and it's somehow different with the wildcard *. but as i said, this is just a guess, if i find out the exact reason i'll gladly share ( btw, if it solved your problem dont forget to accept the answer ;) )Observation
Than you. However, the main reason for putting up this question here is to get an explanation as to why the program worked with A.java source file in the wrong folder, but with import statement using the class name explicitly, instead of wildcard * ?Schmitt
C
2

every thing is in right place, java does not ask to put your A.java file, in the helpers folder

the whole reason why your code ran with the A.java file removed and not otherwise is: when your app.java (or the main java file which is importing other classes in it, -->) is in a default package then while importing the classes it gives priority to the same directory and not to the package directory(if there exist any file that has the same name as the class file -> and thats why it gives error bad source file A.java -> as it wanted A.class)

And because of that there is a rule in java : That never place a .java file (of the same name)in parallel to the packages

so to solve this problem you have to either remove the file, A.java or rename it (to any other name that does not present in the package) or you can use fully qualified import statement

Cumber answered 23/6, 2017 at 15:11 Comment(0)
C
1

I have the same problem finally,

I was solved.

//Use like this
import com.test.helpers.A;

If u have a more than class in com.test.helpers then u can use import com.test.helpers.*;

Chastain answered 15/11, 2016 at 10:53 Comment(1)
If i solved your problem please accept it @Schmitt broChastain
B
0

If you are not using an editor with auto-save, it might be helpful to check if the code you have written has actually been saved to the java file previously created

Borate answered 7/8, 2021 at 12:1 Comment(0)
D
0

The bad source file error may be wrong if it is preceded by another error (below) which, in my case, provided guidance for how to fix the real problem. From my log file:

Error 1: a\g\GoodClass error:duplicate class: a.g.GoodClass //Not the problem
Error 2: a\b\BadClass error: cannot access GoodClass        //The problem
         bad source file: a\g\GoodClass                     //No, it's fine
         file does not contain class x.y.GoodClass          //How to fix it
         Please remove or make sure it appears in the correct subdirectory of the sourcepath.

Java reports the first line of Error 2 because BadClass is using a wildcarded import, either import x.*; or import x.y.*;.

THE FIX: remove the wildcarded import from BadClass and add only the specific imports you need from library x.y.

Drescher answered 2/12, 2021 at 22:27 Comment(0)
D
0

It happens because when no Package declaration is present, Main class is in default package. It can access all the members of Default package. When it sees A a = new A();[Default package/Current directory]

It tries to find A class file in current directory since A.class file is not present[A.java is present]. It throws error.

Either Delete that Source file[A.java] or put Main class in other package by writing package declaration explicitly.

That's why we cannot access class files without package declaration from other directory unless classpath is not set.

Dingy answered 9/4, 2024 at 16:47 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.