Java file layout without IDE (OS: Ubuntu) - java

I am writing some Java code without IDE, I got a little problem when I try run the code after compiling it. (I am using Ubuntu 64)
$ javac ClassName.java
$ java ClassName
Could not find or load main class ClassName
My directory structure is the following:
Projectname
----- PackageName
---------- className.java
---------- className.class
My code start by writing down the packageNmae. When I remove the package statement, it works. While error occur when that statement is included.
package PackageName;
public class myClass {
// .... to be used in the main class
}
public class ClassName {
public static void main(String args[]) {
// ....
}
}
Could anyone tell me what is the problem.

The main issue is where are you trying to run the command from. You do not run it from inside the package directory, but from the root of your package tree (in your example, the Projectname directory).
From there, you should be doing:
javac PackageName.className
which tells it to compile "className"[sic] inside package "PackageName"[sic]. The way you are doing it, you are telling it to compile a class that is not part of a package (which is strongly discouraged).
Notes:
Each file can only have a "general" class, with the name of that file.
You may define inner classes inside a class, but that would be inside the code block of the class.
package packageName;
public class ClassName {
public class InnerClass {
...
}
public static void main(String args[]) {
...
}
}
File name and class name must be the same. That includes case (lowercase or uppercase) of the name.
Class names always begin in uppercase.
Package names should be in camelCase.
Usually you do not want to leave your compiled (.class) files with the source (.java) files. The usual structure is, at the minimum:
--> Project --> src --> myPackage --> MyClass.java
--> bin --> myPackage --> MyClass.class
so you only need to copy your .class files to distribute the executable.

Related

How to create a single jar from multiple packages?

I want to create a single jar file from multiple packages. I have created the jar using below command but when I'm importing it to a project as a dependency it is not working.
jar cfe output/jar/my-java.jar Main src/pkg1/pkg0/*.class src/pkg1/*.class src/pkg2/*.class
My project structure is something like below structure
src
pkg1
A.java
B.JAVA
pkg0
E.java
pkg2
C.java
D.java
My Example code is something like
import pkg1.A;
public class Main {
public static void main(String[] args) {
A.printMe("Hello World");
}
}
error that I'm getting is:
java pkg1 not exist
But in the editor(IntelliJ), it is not showing errors and also i'm able to import class but not package.
import pkg1: showing red means error in the editor
import pkg1.A: not showing red means no error in the editor
Note: I don't want to use maven.
An unzip -t something.jar shows the actual file structure of the jar file (zip). It is the same as the class structure of it (except that instead "/", a "." is the separator).
In your case, the problem will be that src will be on the top level, and not pkg1. Either import src.pkg1 (very dirty), or play a little bit more with the directories / jar flags.
just call your method it automatic get path if you correctly put your jar in your current project.`project 1
pkg com.test.demo
class test{
public static void m1(){
System.out.println("project 1 in method 1 );
}
}
in project 2 put jar of project 1
pkg com.test.demo
class Test1{
public static void main(String...){
System.out.println(test.m1())
}
}

Java - Use of nonpublic class from the current package makes compiling error

I've the following two source files
File World.java
package planets;
public class World {
public static void main(String[] args) {
Mars.land();
}
}
File Moon.java
package planets;
public class Moon {
public static void land() {
System.out.println("Hello Moon");
}
}
class Mars {
public static void land() {
System.out.println("Hello Mars");
}
}
As we can see, the Moon.java contains two classes: the public Moon class and the nonpublic Mars class.
The files are located inside planets directory, below is showed the directory tree
+current-dir:
+----+planets:
+----+World.java
+----+Moon.java
Now, if I try to compile from Windows command prompt (I'm inside current-dir folder) typing
javac planets\World.java
I receive this error message:
planets\World.java:5: error: cannot find symbol
Mars.land();
^
symbol: variable Mars
location: class World
1 error
It's very strange, because I know that the compiler searches for nonpublic classes inside all the source files of the current package.
Also Cay Horstmann's Core Java Vol 1, 10th ed. at pp. 192-193 says that:
[...]you can import nonpublic classes from the current package. These
classes may be defined in source files with different names. If you
import a class from the current package, the compiler searches all
source files of the current package to see which one defines the
class.
In addition I tried to write these files using Eclipse Oxygen and it compile without problems. But I know that Eclipse use a different compiler.
Why does javac compiler fail?
EDIT: I have not set CLASSPATH variable. So by default compiler looks inside current directory.
you need to type the following commands in order (inside your 'current-dir')
javac planets\Moon.java
javac -cp . planets\World.java
java -cp . planets.World

Must a class name be fully qualified when we already set -classpath to locate that file?

Example:
I have a class called ProgA
package test;
public class ProgA
{
public static void main(String[] args)
{
ProgB pb = new ProgB();
pb.callMe();
}
}
Now I have the ProgB like below:
package test2;
public class ProgB
{
public void callMe()
{
System.out.println("inside callme");
}
}
After compiling ProgB.java its class file is generated in the test2 package. Now when I try to compile ProgA.java using this command:
javac -cp C:\Users\MyName\Desktop\test2 ProgA.java
I get the error that it cannot find ProgB.
My question is why cant java look inside the class path to find ProgB.class file and compile my ProgA.java successfully? The code works fine when I specify the fully qualified class name of ProgB inside ProgA.java code and run with the classpath set to -classpath C:\Users\MyName\Desktop. Why to have the fully quilified name when I am already specifying the full class path to find ProgB. I am not clear with that concept of classpath and fully qualified class name. Please explain me. Thank you
First you would need to import the class. This is why it asks you to use a fully qualified class name. You cannot use a class that is not in the same package without importing it (or using the fully qualified class name).
import test2.ProgB;
Then while compiling, you should provide the class path till the root location, the compiler will look for the class using the package name as the path.
Your compile command should be.
javac -cp C:\Users\MyName\Desktop ProgA.java
In order to use a class from another package, you need to either use the fully qualified class name, or have an import statement. This is a .java source code requirement. It can't be fixed simply by fiddling with the compiler's classpath.
Without an import statement, unqualified names are assumed to belong to the current source file's package. If you're in a package test file, the identifier ProgB will match test.ProgB but not test2.ProgB. The compiler won't search other packages unless you tell it to.

Confusion regarding Java Packages and Windows Directory?

When preparing for the SCJP exam, we were going through the following code:
package certificaton;
public class OtherClass
{
public void testIt()
{
System.out.println("otherclass");
}
}
And this:
package somethingElse;
import certification.OtherClass;
public class AccessClass
{
public static void main( String args[])
{
OtherClass o= new OtherClass();
o.testIt();
}
}
I placed both the above files in the following directory: C:\scjp\temp8 ; and the strange thing is that, the .java files are compiling and results in two .class files being created in the same directory. The thing I want to ask, is that, the difference between packages and directory. Isn't it true that the class files could be created in a directory other than the one stated in the package declaration? And the package declaration is something 'virtual', and disregards the windows directory structure. In addition, isn't it also true that, by executing the following command:
javac -d . OtherClass.java
The directories are created conforming to the package declaration, which isn't always mandatory?
The directories are created conforming
to the package declaration, which
isn't always mandatory?
No, the package and directory structures must match. It's mandatory, not optional.

Can I compile a java file with a different name than the class?

Is there any way to compile a java program without having the java file name with its base class name.
If so, please explain..
To answer the question take a look at this example:
Create a file Sample.java
class A
{
public static void main(String args[])
{
String str[] = {""};
System.out.println("hi");
B.main(str);
}
}
class B
{
public static void main(String args[])
{
System.out.println("hello");
}
}
now you compile it as javac Sample.java and run as java A then output will be
hi
hello
or you run as java B then output will be hello
Notice that none of the classes are marked public therefore giving them default access. Files without any public classes have no file naming restrictions.
Your Java file name should always reflect the public class defined within that file. Otherwise, you will get a compiler error. For example, test.java:
public class Foo {}
Trying to compile this gives:
[steven#scstop:~]% javac test.java
test.java:1: class Foo is public, should be declared in a file named Foo.java
public class Foo {
^
1 error
So you must have your filename match your public class name, which seems to render your question moot. Either that or I don't understand what you're asking... spending some time explaining what you are actually trying to achieve would go a long way towards asking a more effective question :)
As long as you don't have a public class in your source file, you can name your source file to any name and can compile. But, if you have a public class in your source file, that file should have the name same as your class name. Otherwise, compiler will throw an error.
Example:
Filename: TestFileName.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello,World\n");
}
}
Compiling: javac TestFileName.java
Error:
TestFileName.java:1: class HelloWorld is public, should be declared in a file named HelloWorld.java
public class HelloWorld
^
1 error
No, the public class name must match the file name. Inner, non public, class names may differ.
You must have a public class with the same name as the file name. This is a Very Good Thing. You CAN have secondary classes inside the same file as long as they are not public. They can still be "default" though, so they can still be used by other classes in the same package.
This should not be done for the most part. Java's naming patterns regarding classes and packages are one of the bigger advantages it has--makes a programmers life easier at no cost.
You can use the Java Compile API and compile any java source you wish, the source need not come from a file or could come from a file with an unrelated name. It depends on how obtuse you want to develop your program. ;)
yes, we compile a java file with a different name than the class, provided that there should not be any public class in that file.
If there is any public class in file then in that case you have to give that name as file name. But if your class does not contain any public class then you can give any name to you class.
Please refer below example to make it more clear:
file name : sample.java
class A
{
public static void main(String args[])
{
System.out.println("hi in Class A");
}
}
class B
{
public static void main(String args[])
{
System.out.println("hello in class B");
}
}
then compile it with(windows) : javac sample.java
then run it : java A
output : hi in Class A
then run it : java B
output : hello in class B
Please check and confirm.
It is not necessary to name your file same as the name of the class it has, until this class is public. Though it is a good practice to name the file same as the name of class.
The compiler will compile your file successfully and make a dot class file. Now at the run time you need to give class name to the JVM for that you have to keep the name of the class, which has main method, in your mind. If you keep both the file name and the class name same, it will become easy to remember the name of the compiled dot class file.
for example:
file Dummy.java
class Dummy
{
public static void main(String args[])
{
System.out.println("This is Dummy class running");
}
}
to run the above code we will use :
Javac Dummy.java // to compile
Java Dummy //to run
example:
file Dummy.java
class Diff
{
public static void main(String args[])
{
System.out.println("This is Diff class running");
}
}
to run the above code we will use :
Javac Dummy.java // to compile
Java Diff //to run
I guess what he means is the .java file is named differently than the actual class defined inside it.
I guess this is not possible.
No. You could write a shell script to rename the .java file before compiling it, but javac requires that filenames = class names.
(Also in windows, it's case insensitive, so ASDF.java can compile Asdf.class)
yes, you can choose any name for the file (.java). there is no matter to what are the name of classes in that file means that class names may be totaly different from the file name.
you should compile the program with file name and you should run the program with the class name in which the main method exist.
main methods may be multiple in different classes so you should run it with the class name in which the main method you want to run......
we can save the file tootle different name of class name because in java we compile the program but we run the method.
we have to compile our program with file name and run our class name
Yes,it is possible to compile a java source file with different file name but you need to make sure none of the classes defined inside are public...when you compile the source file the corresponding .class files for the classes inside the source file are created.
Yes,you can save your java source code file with any other name, not same as your main class name but when you comiple it than byte code file name will be same as your main class name. So for your ease of not to memorize to many names for java code run, You need to have your file name same as your main class than only your file name and byte code file will be with same name.
If class is not public you can save it using other name like if classname is Simple then save it Hard.java.
complie->Hard.java
run->Simple.java
Save your java file by .java only.
compile javac .java
run java yourclassname
For example if my program main class name is A then
save by .java only
compile by javac .java
run by java A
yes, we can compile a java file with a different name than the class, provided that there should not be any public class in that file.
If there is any public class in file then in that case you have to give that name as file name. But if your class does not contain any public class then you can give any name to you class.
Please refer below example to make it more clear:
file name : example.java
class A
{
public static void main(String args[])
{
System.out.println("You are in Class A");
}
}
class B
{
public static void main(String args[])
{
System.out.println("You are in class B");
}
}
then compile it with : javac example.java
then run it : java A
output : you are in Class A
then run it : java B
output : you are in class B
Please check and confirm.
You can write more than one main methods in java because java provides main method overloading in which main method can also be overloaded . Once you compile the file here example.java
Compiler create .class file which contains main method when you run the file with java A it will run the A.class file whih contains the main method of class A and that output will be display on you screen ,but when you run this file with java B ,It runs the B.class file which provides main method of B class
So your code is run successfully
Yes. This can be done.
The main reason for the class and file name to be same are to make the job of the complier easy to check which class it needs to run, in the whole list of the Java classes.
So it's a good practice to have filename and class name as same.
And you have compile and run a class with different name other than the filename, If you don't have any public methods in this class.
By convention, the name of the main class should match the name of the file that holds the program. You should also make sure that the capitalization of the filename matches the class name.
The convention that filenames correspond to class names may seem arbitrary. However, this convention makes it easier to maintain and organize your programs. Furthermore, in some cases, it is required.
According to the other answers the only viable solution is to somehow determine the classname from the source, then use it to rename the file to proper name and compile it as usual.
Another option is to alter the package and class name in the source to match file name:
sed -i -r "0,/package/s/^\s*package .*?;/package new.klass.pkg;/" %1
sed -i -r "0,/class/s/public\s+class .+?\{/public class NewClassName {/" %1
Via How to use sed to replace only the first occurrence in a file?
You can have your java file even without name ( simply ".java" ). Only thing is you should not have any public class in your file.

Categories