How to compile java package structures using javac
Asked Answered
T

6

22

I am trying to compile (from the command line) a java package that imports another package of my own. I was following a tutorial online but it seems that I get an error when I try to compile the final java file (CallPackage.java).

Here is the file structure:

+ test_directory (contains CallPackage.java)
   -> importpackage
       -> subpackage (contains HelloWorld.java)

Here is CallPackage.java:

/// CallPackage.java
import importpackage.subpackage.*;
class CallPackage{
  public static void main(String[] args){
  HelloWorld h2=new HelloWorld();
  h2.show();
  }
}

and here is HelloWorld.java:

///HelloWorld.java

package importpackage.subpackage;

public class HelloWorld {
  public void show(){
  System.out.println("This is the function of the class HelloWorld!!");
  }
}

Attempted Steps

  1. Go to the subpackage and compile HelloWorld.java with $javac HelloWorld.java.
  2. Go to test_directory and compile CallPackage.java with $javac CallPackage.java.

This gives me an error on the last command:

CallPackage.java:1: package importpackage.subpackage does not exist
import importpackage.subpackage.*;
^
CallPackage.java:4: cannot find symbol
symbol  : class HelloWorld
location: class CallPackage
  HelloWorld h2=new HelloWorld();
  ^
CallPackage.java:4: cannot find symbol
symbol  : class HelloWorld
location: class CallPackage
  HelloWorld h2=new HelloWorld();
                    ^
3 errors

How can I compile both packages? Thanks so much for any help!

Tor answered 15/10, 2013 at 13:32 Comment(2)
this will help you. thejavageek.com/2013/07/21/…Dodecanese
It is better if you use an IDE like Eclipse to execute java programs, as it can create packages automatically.Iredale
I
4

Are you sure importpackage/subpackage is in your classpath?

-cp path or -classpath path

Specify where to find user class files, and (optionally) annotation processors and source files. This class path overrides the user class path in the CLASSPATH environment variable. If neither CLASSPATH, -cp nor -classpath is specified, the user class path consists of the current directory. See Setting the Class Path for more details.

If the -sourcepath option is not specified, the user class path is also searched for source files.

If the -processorpath option is not specified, the class path is also searched for annotation processors.

http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html

Item answered 15/10, 2013 at 13:38 Comment(3)
I am guessing @Jazzy Josh that you are saying that when I execute step 2, I need to make my class path point to the directory that the .class file from step 1. When I did this I ran this: $javac -cp importpackage/subpackage/ CallPackage.java but I got this error: Please remove or make sure it appears in the correct subdirectory of the classpath. HelloWorld h2=new HelloWorld(); ^ 2 errorsTor
the issue did end up being the class path. I needed to run all java and javac commands with "-cp ." For example: $javac -cp . CallPackage.java and $java -cp . CallPackageTor
@Jazzy Josh Would please take a look at this post, I guess I am using -cp in a wrong way, and I don't how to correct my mistake.Turret
T
14

The issue was that the class path needs to be set for each command (javac and java):

Attempted Steps

  1. instead of going to subpackage, compile HelloWorld.java from the top_level:

    $javac -cp . importpackage/subpackage/HelloWorld.java

  2. compile CallPackage.java in the same way:

    $javac -cp . CallPackage.java

  3. run the file using the class path also:

    $java -cp . CallPackage

NOTE: running "$java CallPackage" will give an error "Error: Could not find or load main class CallPackage"

In summary, during each step, the class path must be specified. It worked after running it as such.

Tor answered 15/10, 2013 at 20:2 Comment(1)
This doesn't work on Windows if your classes at all reference each other...Adjutant
G
13

Same situation to me. And I came to take over it by compiling classes at the same time.
For example, here is my project:

+ beerV1
   -> classes
   -> src
         -> com
              -> example
                   -> model
                        -> BeerExpert.java
                   -> web
                        -> BeerSelect.java


BeerExpert.java:

package com.example.model;
import ...

public class BeerExpert{
    ...
}


BeerSelect.java:

package com.example.web;
import com.example.model.*;
import ...

public class BeerSelect {
      ...
}


As you can see: BeerSelect.java is trying to import classes in com.example.model package.
At the first time, I compiled BeerExert.java first by command:

--> javac -d classes src/com/example/model/BeerExpert.java

Then:
--> javac -d classes src/com/example/web/BeerSelect.java

And the result was:
-->... error: package com.example.model does not exist

So, I knew that compiling multiple classes separately will not work in this case.


After suffering on google, I found this very simple way to solve the problem:
Just compile all at once:

--> javac -d classes src/com/example/model/BeerExpert.java src/com/example/web/BeerSelect.java 


Finally, here is what I got:

 + beerV1
           -> classes
                 -> com
                      -> example
                           -> model
                                -> BeerExpert.class
                           -> web
                                -> BeerSelect.class
           -> src
                 -> com
                      -> example
                           -> model
                                -> BeerExpert.java
                           -> web
                                -> BeerSelect.java

Hope that helps.

Guevara answered 5/1, 2018 at 8:30 Comment(2)
Thank you. This is definitely the best answer! Other answers cause obviously expected issues since I CANT compile one without the other!Adjutant
Had a similar problem. Vĩnh Thụy Trần's solution works nicely: with the command prompt at the top level of your project, including all the classes with their paths on the same javac line, who would have thought it was that simple!Stomatic
I
4

Are you sure importpackage/subpackage is in your classpath?

-cp path or -classpath path

Specify where to find user class files, and (optionally) annotation processors and source files. This class path overrides the user class path in the CLASSPATH environment variable. If neither CLASSPATH, -cp nor -classpath is specified, the user class path consists of the current directory. See Setting the Class Path for more details.

If the -sourcepath option is not specified, the user class path is also searched for source files.

If the -processorpath option is not specified, the class path is also searched for annotation processors.

http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html

Item answered 15/10, 2013 at 13:38 Comment(3)
I am guessing @Jazzy Josh that you are saying that when I execute step 2, I need to make my class path point to the directory that the .class file from step 1. When I did this I ran this: $javac -cp importpackage/subpackage/ CallPackage.java but I got this error: Please remove or make sure it appears in the correct subdirectory of the classpath. HelloWorld h2=new HelloWorld(); ^ 2 errorsTor
the issue did end up being the class path. I needed to run all java and javac commands with "-cp ." For example: $javac -cp . CallPackage.java and $java -cp . CallPackageTor
@Jazzy Josh Would please take a look at this post, I guess I am using -cp in a wrong way, and I don't how to correct my mistake.Turret
L
1

It's an old topic but Google has led me to this site. For the completness, I'd like to add one bit to @Vĩnh Thụy Trần's answer on how to run the main class after compiling it into a custom folder. While it looks trivial now it took me some time to get it right.

In order to run your project, you also need to specify a path to the classes:

java -classpath <directory> your.package.name.classname

or

java -cp <directory> your.package.name.classname

Taking Vĩnh Thụy Trần's example again, the command would look like this:

java -cp classes com.example.web.BeerSelect

I hope it will help someone as I spent some time figuring it out.

Leyte answered 25/4, 2021 at 11:58 Comment(0)
S
0

(1)first compile the code

javac -d importpackage.subpackage.HelloWorld

(2) and then compile the CallPackage.java

javac CallPackage.java

Seleta answered 15/10, 2013 at 13:46 Comment(2)
what directory should I run the cmd from the first step? When I try this in both the test_directory and the subpackage dir, I get an error saying that it can't find this directory.Tor
because you compile the HelloWorld inside the subpackage.Seleta
P
0

delete your package folder (after pasting you code to some other folder) and then locate to the folder in cmd where you current code is and try javac -d . Helloworld.java (this will create the Helloworldclass and subpackage as well) and try same for you mainfunction code ie Callpackage.java after compiling to run the code try java Callpackage

Pathe answered 18/9, 2020 at 15:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.