How to create the empty package in Java? - java

I have the following directory structure:
A.java
a
โ””โ”€โ”€ A.java
A.java:
import a.*;
class A {
public static void main(String[] args) {
System.out.println("Hello Human");
}
}
a/A.java:
package a;
public class A {}
And it compiles and runs:
$ javac A.java && java A
Hello Human
But when I remove a/A.java (but keep the folder a), I can no longer compile it:
$ rm a/A.java
$ javac A.java && java A
A.java:1: package a does not exist
import a.*;
^
1 error
Why?

You might say that the package a is not observable:
A package is observable if and only if either:
A compilation unit containing a declaration of the package is observable (ยง7.3).
A subpackage of the package is observable.
source: Observability of a Package

This is your problem right here:
import a.*;
It's looking for something that doesn't exist, since that package is no longer there.
Remove that line from A.java and it should work fine.
The reason it can't find the package is because there is no compilable classes within the folder, and so it isn't recognised as a java package.
One option for creating an empty package, if you do need one, would be to specify a package-info.java file, which is generally used as a javadoc for packages.

Related

Can we create more than one package in single Java file?

Can we create more than one package in a single .java file? Like:
package parent;
package parent.child; // parent exists already from the previous command
package dada.papa.beta; // dada & papa does not exits but -> for creating beta java will automatically create dada & papa
public class b{
/* see the ReadMe.txt file
here i am just creatign packages;
*/
public static void main(String[] args) {}
}
I just wanted to practice making lots of packages and sub packages in a single go.
Error:
Unix-Box ~/making_sub_packages$ javac -d . b.java
b.java:2: error: class, interface, or enum expected
package parent.child;
^
b.java:4: error: class, interface, or enum expected
package dada.papa.beta;
^
2 errors
No, you can't do that.
The package statement must be the first line in the source file. There can be only one package statement in each source file, and it applies to all types in the file. You can read more here:
https://docs.oracle.com/javase/tutorial/java/package/createpkgs.html

Java compiler doesn't compile all subfolders after the first compile

I have a problem with the java compiler.
The folders of my java project looks like this:
main folder
delivery folder
Box.java
Factory.java
FragileBox.java
Supplier.java
test folder
Test.java
Test2.java
Test3.java
Test4.java
Test5.java
DeliveryTest.java
Clearly I have 2 packages aswell, a delivery package and a test package. It's a school project, so the test package was given, we had to write the delivery package which is tested by the test package.
The DeliveryTest.java looks like this:
import java.util.ArrayList;
import java.util.List;
import test.*;
import delivery.*;
public class DeliveryTest {
public static void main(String[] args) {
List<Test> tests = new ArrayList<Test>();
tests.add(new Test2());
tests.add(new Test3());
tests.add(new Test4());
tests.add(new Test5());
int level = 1;
for (Test test : tests) {
if (test.test()) {
++level;
}
}
System.out.println("Az elert szint: " + level);
}
}
I really don't want to detail the work and the purpose of the code, I don't think it's relevant here.
My problem is that if I compile the DeliveryTest.java as javac DeliveryTest.java, it creates the class files, and successfully compiles, but: after the first compile, when all the class files created I make any changes on delivery package it won't compile again, only the test package, and after compiler finishes the compile it will just return as everything went well. It won't even create the class files again if I remove one of the class files from the delivery folder. However, the test package compiles fine after the first compile, it has no problem with that.
How can I achieve that I can compile the delivery package aswell after the first compile?
Thanks for any help
The Java compiler doesn't look around for files to compile. If you call it from the command line, you better use a call that names all Java files in their folders. Assuming that the main folder is your working directory,
javac DeliveryTest.java delivery/*.java test/*.java
If you don't change files in the test package you may not have to use the last parameter.

Relationship between a package statement and the directory of a .java file?

Consider a package hierarchy folder1/hi. folder1 contains B.java and hi contains A.java.
B.java:
package hi.a12.pkg;
public class B { }
A.java:
package a12.pkg;
public class A {B b; }
Now B.java compiles successfully, but A.java does not.
Since both should produce class files in same location. Hence they should be able to find each other without import statement.
But still It says class B not found.
Anyone suggest the measures...or whats going wrong..
Consider a package hierarchy folder1/hi. folder1 contains B.java and
hi contains A.java.
So B.java is in folder1 and A.java is in a folder named hi. So far so good.
B.java looks like this :
package hi.a12.pkg;
public class B { }
Oops. B.java says that it is in a package named hi.a12.pkg and yet it's physical location on the disk is folder1. That's where the problem is. Put your files in the folder indicated by the package statement or else other classes will not be able to find them.
A quick way to understand the concept and fix your problem would be to :
Change the package statement in B.java to package folder1;.
Change the package statement in A.java to package folder1.hi;
import B in A.java after the package statement as import folder.B;
Compile B.java from one directory above folder1 as javac folder1\B.java
Compile A.java from one directory above folder1 as javac folder1\hi\A.java
You can read all about it in the Oracle documentation
There are several problems.
First, it looks like your packages are named the wrong way around. Try
for A.java (which should be in the directory ..../pkg/a12):
package pkg.a12;
for B.java (which must be in the directory .../pkg/a12/hi):
package pkg.a12.hi;
Second, your file A.java needs to say where B is located using an import statement:
package pkg.a12;
import pkg.a12.hi.B;
public class A {B b; }
Third, when you compile A you must be in the folder above pkg and refer to the full path of A:
javac pkg/a12/A.java
This will also compile B.java

How to import my own class?

I have this java class :
package myClass;
public class myClass
{
private int herAge ;
public void setHerAge (int herAge)
{
this.herAge = herAge ;
}
}
and I want to import this class after compile it in another source file called Test.java exists in the same directory , and here what Test.java contains :
import myClass ;
public class Test
{
public static void main (String []args)
{
myClass Rudaina = new myClass();
Rudaina.setHerAge(30);
}
}
when I compile Test.java I see this in my console :
Test.java:1: error '.' expected
import myClass ;
^
Test.java:1: error '.' expected
import myClass ;
^
Your class myClass is also in package called myClass, which can be a cause of confusion.
Try:
import myClass.myClass;
This is called the fully qualified name of the class.
A package is meant to group classes which are conceptually related. Having a package named after a single class is not very useful.
You could name your package after the name of your project. For instance, you could name it
package assignment1;
And then import your class like this:
import assignment1.myClass;
While what everyone wrote is true, since the two files are in the same directory, no import should be necessary.
FYI, it is customary to capitalize the names of classes.
It's better to put the same package name or a different one as mention below on top of the Test.java file;
package myClass; //or some other name also viable
Then when you compile you can do like this;
javac -d . myClass.java
javac -d . Test.java
The -d specifies the destination where to put the generated class file. You can use any directory name like /home (in case of Linux), d:/abc (in case of windows), etc. If you want to keep the package within the same directory, you can use the .(dot).
After that use the import statement inside Test.java like this;
import myClass.*;
or
import myClass.myclass;
After that when you run the Test class do like this;
java myClass.Test //myClass in here is package name if you use some different package name use that
You should use the whole class name - including the name of the package.
You are missing the package name. Try import myClass.myClass;

Interface Implementation error : cannot find symbol

I am implementing the following sample interface:
package test1;
public interface MotorVehicle {
void run();
int getFuel();
}
In the class
package test1;
import test1.MotorVehicle;
public class Car implements MotorVehicle
{
int fuel;
public void run(){
System.out.println("Running");
}
public int getFuel(){
return this.fuel;
}
}
When I try to compile the class file , I get the following error :
Car.java:4: error: cannot find symbol
public class Car implements MotorVehicle
^
symbol: class MotorVehicle
1 error
Compile Steps:
Step:1 javac MotorVehicle.java
Step:2 javac Car.java
Both my interface and the class are in the same directory , why does ut come up with cannot find symbol error?
Edit:
As suggested , have changed the package , and tried to run the same code again . Still getting an error.
The problem is that you're in the wrong folder when compiling.
From the console screenshot, it is clear that you are inside /test1. However, the package test1; statement expects a folder inside the current folder named test1. It can't find that folder/package, so you get an error.
The solution is to go up one folder, so you end up in /src, then compile using the path to the file, e.g. javac test1/Car.java. Explanation: You are in the folder /src, the package statement inside the classes says they are inside the folder test1 which is inside /src. Now every package/path can be resolved.
And you shouldn't import things that are in the same package.
First of all as your package name is test you must keep your class and the interface in a folder named test.
Second thing since they are in the same folder named test remove import test.MotorVehicle; from the class defination
Suppose if your folder test resides in g:/ such that g:/test/contains class and the interface.
Then try opening the command prompt in g:/
then type the following commands
for compiling
javac test/Car.java
and for executing
java test.Car
Though you may get Error: Main method not found in class test.Car
as your class does not contain main mathod
You are going in to exact path by the use of cd command.Because of that interface is not accessible as class will try to find out it from package from current/running location.
For make this compile you have to specify fully (again Fully) qualified name of package during compilation.
For Example
If you class is in a.b.test package compile it like this
javac a/b/test/Car.java
First compile MotorVehicle as it doesn't have any dependencies. Then set the classpath
Before issuing javac Car.java compile statements you need to set the Classpath
Windows
set CLASSPATH=%CLASSPATH%;<PATH_TO_COMPILED_BINARY>/
Unix
export CLASSPATH=$CLASSPATH:<PATH_TO_COMPILED_BINARY>/
<PATH_TO_COMPILED_BINARY> should not include the package test1
Example :
C:/sourcecode/test1
Then <PATH_TO_COMPILED_BINARY> should be C:/sourcecode
Update
Removing the import test1.MotorVehicle will also fix the issue.
After Compiling Motorvehicle.java. you have to create a folder test1 and transfer the MotorVehicle.class into the folder test1 then compile the next file Car.java. This will solve your error

Categories