About compiling Java through terminal javac - java

I am a Java newbie, just started learning it in college, and my class is using NetBeans but I'd like to use VSCode.
The professor told us that every Java file should start with:
package nameofthepackage
So that Java knows to which package the class (file) I created belongs to.
So I always create this structure:
I create a folder with the name of the main class, and inside this folder I make a src folder that will store the Java files. Eg:
MyJavaProject/src/MyJavaProject.java
I always name the main .Java file the same as the project folder name.
And when I compile I use javac with the -cp parameter to specify that the src folder is the classpath folder, where it should look for the .Java files I create.
I also always tell javac to compile all the files inside the src folder, using the * wildcard.
The issue is that with this line on top of my .Java files, javac compiles all the files, but I can't execute the bytecode because it complains it can't find the classes I created, even the main one.
As Soon as I remove the package line from the top of the files, I can compile and run the code.
So far it's good, but for any more complex projects this is gonna be really annoying.
Any ideas how can I fix this?

You need to specify the full name (with package) of the class that contains the main function.
Assuming the class MyJavaProject is the one containing your main, that would be:
java nameofthepackage.MyJavaProject
This is assuming you built it with
javac -d . MyJavaProject.java
It would create your target class in a directory structure like:
nameofthepackage\MyJavaProject.class

Related

When use package, the javac only work in parent directory?

I use cmd to compile my java applications, but when I use package to pack all the files, if I try to compile them in the working directory, even if I use full path of the file, that won't work. But when I go to the parent directory, the same command works. And only works in parent directory, children directories or other directories also won't work. Can somebody tell me why? or is there any solution that make javac work in the working directory, because I use Sublime Text, its builder configs and binds the working directory.
Read https://docs.oracle.com/javase/tutorial/java/package/managingfiles.html to understand how Java source files should be organized. Espcially,
... put the source file in a directory whose name reflects the name of the
package to which the type belong...
By default the source code for my.pkg.MyClass must reside in current_directory/my/pkg/MyClass.java. You can use other than current directory with javac option -sourcepath.
For example you have two classes in two different packages packagea and packageb laying in the parent directory.
And class names are ClassA.java and ClassB.java respectively, and you have packaged your classes in these packages then you have
to use javac command in parent directory like this:
javac packagea\ClassA.java packageb\ClassB.java
Your directory structure will be like this:
Parent_directory
|
|--packagea->ClassA.java
|--packageb->ClassB.java
Otherwise, you can use any build tool like ant or maven to compile
your code. You have to just run build.xml file and your all files will
be compiled.

How to execute a large compiled Java project via command line, without using any software (Windows)?

I have a Java project with 5 packages and 30 classes. I want to test this project on a different computer, but I can't install any sotware on that computer so I can't use things like Maven, Eclipse etc. Is there a way I can execute the program on that computer?
What I tried to do, is to compile the project using Eclipse on my computer, then went to the other computer and tried to execute the project main class via the folder that the main class .class file is at.
I.E., say that the main class name is Hello in package Greetings and Hello.class is at folder named folder. So I opened the command line window at folder and typed the command:
java Greetings.Hello
That didn't work....
Edit: After doing this I got the message: Error: Could not find or load main class Greetings.Hello
If the package name is Greetings and you want to run Hello.class
Hello class must have main method.
Hello.class must in folder name Greetings (package name).
Execute java Greetings.Hello from the one level above of Greetings folder
It seems to me Hello.class is not inside of Greetings folder
If javac is installed on the system you can directly compile on the system. you can compile even large projects including many packages with choosing different options provided by javac.
The javac tool reads class and interface definitions, written in the Java programming language, and compiles them into bytecode class files. It can also process annotations in Java source files and classes.
There are two ways to pass source code file names to javac:
For a small number of source files, simply list the file names on the command line.
For a large number of source files, list the file names in a file, separated by blanks or line breaks. Then use the list file name on the javac command line, preceded by an # character.
Source code file names must have .java suffixes, class file names must have .class suffixes, and both source and class files must have root names that identify the class. For example, a class called MyClass would be written in a source file called MyClass.java and compiled into a bytecode class file called MyClass.class.
Inner class definitions produce additional class files. These class files have names combining the inner and outer class names, such as MyClass$MyInnerClass.class.
You should arrange source files in a directory tree that reflects their package tree. For example, if you keep all your source files in C:\workspace, the source code for com.mysoft.mypack.MyClass should be in C:\workspace\com\mysoft\mypack\MyClass.java.
By default, the compiler puts each class file in the same directory as its source file. You can specify a separate destination directory with -d source
Given that you have Eclipse and you ran the code in Eclipse: the quickest way is to use Eclipse and export it to executable JAR.
If you have Run Configuration (e.g. named Hello) that you use for running the code:
Menu -> Export -> Runnable JAR file
Launch Configuration: Hello
Select export destination: (e.g. C:\tmp\Hello.jar)
Set Extract required libraries into generated JAR
Click finish.
This will create Hello.jar file you can execute typing in:
java -jar Hello.jar

Java compilation error cannot find symbol of interface

I am trying to implement an interface in my java code as such:
package PJ1;
public class Fraction implements FractionInterface, Comparable<Fraction>{
Now, FractionInterface.class in the same directory as the Fraction.java file, and it is also in package PJ1:
package PJ1;
public interface FractionInterface{
Yet when I try to compile my Fraction.java file, I get the following error:
D:\CSC220\PJ1\Fraction.java:36: error: cannot find symbol
public class Fraction implements FractionInterface, Comparable<Fraction>
^
I'm stumped, since all of my related files are in the same directory and I'm trying to put all of my class files in the same package. Any ideas?
try to compile like this:
e.g. in c: you do have both the java files - Fraction.java and FractionInterface.java , and you have not created any folder for packages yet, then try as:
c:> javac -d . *.java
This will compile all the files with creating required packages. You no need to create any folders for packages manually.
If you already have created the folder for packages, and you are already in the package say:
c:\PJ1, you can simply compile using javac as:
c:\PJ1> javac *.java
Hope this will work.
My guess is that the files are not in a directory called PJ1 relative to where the compiler expects them to be. Create the folder and move both files to that location. To make it a bit clearer, let's say your folder structure looks like this
myfolder
+-PJ1
Fraction.java
FractionInterface.java
Then you need to be compiling from myfolder using
javac PJ1\Fraction.java
Be sure that both files are in PJ1 folder and run javac *.java.
Just go to a directory above the directory in which your files exist and compile your java files from there (so that you can see if they compile correctly), e.g.
javac dir1\file.java.

Default Directory for packages

I am a newbie in java I Want to know that what is the default directory for packages in java ? I Mean if i compile a java file which contains a package statement,and i compile it without using -d option in javac command,then where will be the package created ? eg.
package test;
class Test{}
and compile it using javac Test.java
then where will be the package created?
Thanks
If you don't specify -d, the class file will be created in the same directory as the source file.
That's fine if you're already storing your source in a directory structure matching your package structure (and if you're happy for your source and class files to live in the same place) but if your source structure doesn't match your package structure, you'll basically end up with class files in locations where they can't sensibly be used.
Personally for anything other than quick throwaway (usually Stack Overflow :) code I would make the following suggestions:
Avoid using the default package
Keep your source code in a directory structure (e.g. with a root of src) matching package structure
Generate class files into a separate directory structure (e.g. with a root of bin or out or classes)
(Sorry, misread the question to start with.)
-d option in javac command is use to specify where to generate the class file,if you don't specify it,then the .class file will be created in the same directory where your .java file is present.
There is no directory created when you do not specify the package!
all the .class files will be created directly in the output folder
public class A{}
if you compile this to output folder ,
output/a.class is created

Package name is different than the folder structure but still Java code compiles

I am using Notepad++ to write my Java code and Command Prompt to compile and run it.
Following is my sample Java code,
package abraKadabra;
public class SuperClass{
protected int anInstance;
public static void main(String [] abc){
System.out.println("Hello");
}
}
However, this file is in the following folder structure :
"usingprotected\superPkg" (usingProtected is a folder somewhere in the hierarchy in C:)
So, my package name here should be something like usingProtected.superPkg instead of abraKadabra as I wrote it.
But, when I compile this Java code from command prompt, it compiles fine with no error or warnings. Why is it so? Shouldn't the package name adhere to the folder structure?
And if it should, how would it adhere?
For e.g. if my package name is usingProtected.superPkg, will the compiler check in the reverse order. The present working directory should be superPkg, then the parent directory should be usingProtected and its done. Is it how it checks the folder structure with package name?
The Java language specification doesn't force files to be in a certain directory. It optionally allows the compiler to require that public classes are in files with the same name of the class, but I don't think there's anything similar for packages. Section 7.2.1 talks about possible storage options in a file system, but it doesn't say anything about enforcing source code structure, as far as I can see.
However, it's best practice - and a pretty much universally accepted convention - to reflect the package structure in the source directory structure... and javac will use this to try to find source files which aren't explicitly specified to be compiled.
Note that if you're compiling from the command line, by default each class will appear in the same location as the corresponding source file, but if you use the "-d" option (e.g. "-d bin") the compiler will build an appropriate output directory structure for you, rooted in the specified directory.
After experimenting a bit, I got the way how to use package name and run Java class files from command prompt.
Suppose following is my Java source file:-
package mySample;
public abstract class Sample{
public static void main(String... a){
System.out.println("Hello ambiguity");
}
}
This file is in directory "D:\Code N Code\CommandLine".
Now, when compile the source code (by going to the above directory from cmd) using following command:-
javac -d . Sample.java
This automatically creates "mySample" folder in my current directory. So, my class file Sample.class is present in directory "D:\Code N Code\CommandLine\mySample". Compiler created this new folder "mySample" from the package name that I gave in my source code.
So if I had given my package name to be "package com.mySample", compiler would create two directories and place my class file in "D:\Code N Code\CommandLine\com\mySample".
Now, I am still in the present working directory i.e. in "D:\Code N Code\CommandLine". And to run my class file, I give the following command:
java mySample.Sample
So, I give the complete hierarchy of package and then the class name. The Java Interpreter will search the current directory for "mySample" directory and in that for "Sample.class". It gets it right and runs it successfully. :)
Now, when I asked that why it compiles my wrong package source code, it would compile the code successfully though, but it gives NoClassDefFoundError when I run my class file. So above method can be used to use package names from command line.
If you're compiling a single class, javac doesn't need to look elsewhere for it. It'll just compile the file as is and put the resulting .class into the same folder. However, you generally won't be able to use the class til you put it into an "abraKadabra" directory in one of the directories in the class path.
If your class uses another class in the package, though, you might have problems compiling it where it is, for the same reason (javac wants to find the class and make sure it has the methods and such that your class uses).
Java compiler does not check the directory structure when it compiles source files. As you mentioned, suppose you have a source file that starts with the directive
package abraKadabra;
You can compile the file even if it is not contained in a subdirectory .../abraKadabra . The source file will compile without errors if it doesn’t depend on other packages. However, the resulting program will not run (unless also including package name in execution). The virtual machine won’t find the resulting classes when you try to run the program.

Categories