Uncompiled java class but still executes - java

I have following piece of code in one of my java program.
public class Solution {
public static void main(String[] args) {
System.out.print("Hello World");
}
public static void printOutput(String[] arr){
//Note: The semi colon is omitted intentionally.
System.out.print("Hello Incomplete World")
}
When I build it I get a compilation error but still it generates a .class file. when I run the .class file, it gives an output of "Hello World".
How is this possible ? I always believed a .class file having unresolved compilation problems will never be an executable one. Can anyone provide some information on that ?

What's probably happening here is that a successfully compiled class file already exists. When the Java compiler runs, it'll produce a .class file if it compiles a source file successfully, but it will not remove subsequent compilation fails.

You're assuming the compiler will clear out your old class files - it doesn't.
Check the modification date on your current .class file - you'll see that it's older than your compilation. That's because it was generated from working code, not from your current source file. If you delete this class file, then try to recompile, you'll see that a new class file is not created.

The class file you are running is from a previous compilation. Compile your program again and look at the time the class file was previously modified.

Related

Java program runs yet compilation fails

I wrote a Java program whose filename was (intentionally) different from the class I wrote inside the file. The javac command failed as expected on both CMD and WSL. The java command however worked and ran my print statement. I wrote the code intentionally this way so there is no way it was a previously compiled version of the code. The following code was written in a file called "explainJava.java" (notice the filename is different from the class name).
public class explain{
public static void main(String[] args) {
System.out.println("Java is weird");
}
}
I've had to google this myself, but I think I've found an explanation in this article.
According to that source as of Java 11 java is capable of compiling a single source file into memory.
What I conclude from that: When the file is compiled into memory and not written to disk it obviously cannot have a file name. If there is no filename there is no such thing as a wrong filename, therefore the code executes.
Please also note that the restriction of having to name a file like the public class within that file is more of a design decision to make work for the compiler easier/ faster. It is not a physical restriction so to speak. Have a look at the following thread for more details.
If you put this code:
public class explain {
public static void main(String[] args) {
System.out.println("Java is weird");
}
}
into a file named explainJava.java, and then compile it with this:
javac explainJava.java
you will get an error that correctly informs you that your filename ("explainJava") and the class defined inside that file ("explain") do not match:
explainJava.java:1: error: class explain is public, should be declared in a file named explain.java
public class explain{
^
1 error
If you run this command:
$ java explainJava.java
Java is weird
you see expected output, because you're skipping the explicit compilation step (that is, you aren't running javac first) and instead relying on behavior introduced in Java 11 that allows you to compile+run in a single step. Here's an explanation: Does the 'java' command compile Java programs?
So the answer is to either:
rename your file to match the class, so change the filename to "explain.java", or
rename the class to match the file, change public class explain to be public class explainJava

Executing the single code java file using java Vs javac using jdk11

I am using JDK11. Below is my sample class -
public class SayHi {
public static void main(String[] args) {
System.out.println("Hi There");
}
}
I executed the above class with command "java filename.java" for below scenarios
ColumnA -> Class declared as public?
ColumnB -> File name same as class name?
ColumnA ColumnB Result
Yes Yes Yes
No Yes Yes
*Yes No Yes
No No Yes
For all the scenarios, the command executed successfully and I got the result. I get compile-time error for the "Yes-No" case, if I run the "javac" command on the file name.
Why I am not getting the compile-time error when I am executing "java" command on the file name?
I have multiple public classes in a single code file. I am able to execute the file using "java filename.java" command. What I am missing with the compile-time issues when running the file with "java" command. Please help me on this.
The answers to all your questions can be found in JEP 330. I believe the following excerpts provide answers to your questions.
the first class found in the source file is executed
The source file should contain one or more top-level classes, the first of which is taken as the class to be executed
The compiler does not enforce the optional restriction defined at the end of JLS §7.6, that a type in a named package should exist in a file whose name is composed from the type name followed by the .java extension
In other words, when you compile a java source code file with javac, the source code file must contain a single, "public" class whose name matches the name of the file. But when you run a java source code file using the java command, the above restriction does not apply.
The class to be executed is the first top-level class found in the source file. It must contain a declaration of the standard public static void main(String[]) method.

Trying to compile Java source (could not find main class)

Trying to learn Java again and I cannot remember how I figured this out the first time around.
I have 3 classes; a GameLauncher, GuessGame, and Player. GameLauncher has my main method.
They are all packaged as chap02, I cannot remember if that is important to me yet.
I am compiling like this: javac GameLauncher.java GuessGame.java Player.java
running like this: java GameLauncher
I am getting this error: Could not find or load main class GameLauncher.
I know this is a ridiculous issue, but I have always had trouble with this kind of stuff. The actual programming and writing code I can pick up just fine, but dealing with these damn compilers always gets me. Any help would be appreciated. Thanks
package chap02;
public class GameLauncher {
public static void main (String[] args) {
GuessGame game = new GuessGame();
game.startGame();
}
}
Edit: The issue isn't with the actual code, the issue is with how I am compiling it.
When running the program, you have to run it form the correct directory. Remember, that you used packages, so you have the following package-structure
src
chap02
GameLauncher.java
GuessGame.java
Player.java
after compilation, you will find the corresponding .class-files in the chap02-folder. To start the game, you have run the following command from the src-directory:
java chap02.GameLauncher
Since you specified a package in the source code, you have to use the full qualified name, including the package, to which the class belongs.
EDIT as vefthym mentioned, you have to compile the code in the same way, running
javac chap02/GameLauncher.java
from the source-directory.
EDIT 2
"src" is the directory, where your src lies. I, for example, have my Code unter X:\JDK-Projects[Project-name]\src. You have to specify the full absolute path to the src-Directory or the relative path form the directory you are currently in.

Getting "class does not have a static void main method accepting String[]" error even though main signature is correct

My DrJava was working fine, but now I keep getting the folowing error whenever I run anything:
Static Error: This class does not have a static void main method accepting String[].
So it will compile OK, but then it shoots out the error . This happens even though everything I test does indeed have a public static void main(String[] args) in it. It seems like a classpath/resources type of error. I appreciate any tips
EDIT: my class
public class Test{
public static void main(String[] args){
System.out.println(" hashmap ");
}
}
There's nothing wrong with the code, so the problem must be with the environment.
Check that you're actually executing that class. Find out where the class that's executed is specified and check it's correct
Check that you're compiling the class. Maybe the code you're looking at has not been compiled and you're trying to execute an old version that was compild before you coded a main()
Check your classpath. Is the compiled class accessible in the classpath of the java command
You don't need to reinstall java, nor is it a java version issue. It may be the way that your are running the program.
To check if it is a problem with your code, do the following:
Make a new folder and put Test.java in it.
Open up Command Line Or Terminal and change to that folder .
Type javac Test.java. Test.class should be in the folder now.
If you want, open up the class with a text editor. This is what I get:
˛∫æ2
<init>()VCodeLineNumberTablemain([Ljava/lang/String;)V
SourceFile Test.java hashmap Testjava/lang/Objectjava/lang/SystemoutLjava/io/PrintStream;java/io/PrintStreamprintln(Ljava/l ang/String;)V! *∑±
% ≤∂±
Back to the command line or terminal, type java Test.
If you get an error, which you shouldn't, I don't know what to say. It should produce the string " hashmap " on to the command line or terminal.
Why re-installing Dr. Java may not work is because you may be using the same working directory, causing same run settings to be used. Dr. Java may be running an external program, one without a main method.
I think that you should install the Eclipse IDE for Java. It is much easier to get around, it looks nicer, and it runs the file or project that you are looking at currently.
Sometimes this problem happens because may be mistake in saving file.you always your file using double quotes and with the .java extension which is main class means that class containing main method.
you should save your file by class name which is public .if there is two classes and both have main method then you should save your file by class name that is public and that class will be run.As like your compiler looking for main method in public static void main(String [] args) that is contract for jvm to run a programme
so it is not able to found that main method that is static and it looking for your Dr class.java
See this Example it have two main methods and practice these kinds of question.I also got this kind of problem in starting.
public class TestFirst
{
public static void main(String [] args){
System.out.println(" TestFirst ");
}
}
class Test{
public static void main(String [] args){
System.out.println(" hashmap ");
}
}
if you save pro-gramme by "TestFirst.java" then o/p will come TestFirst if you do some mistake in main method because we have saved our programme by TestFirst then you will get error like you got.
# 2nd mistake may be this
debian#debian:~/Geany_java$ javac Test1.java
debian#debian:~/Geany_java$ java Test1
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
at Test1.main(Test1.java:11)
your classpath has not set properly See above Compiling successfully but running showing same kind of error you got.Which OS is using I can guide you properly.
Check that actually your file have the .java termination nor the .dj
There is nothing wrong with the code.
It is the executing environment which might have problem. Please share the details.
Check if program compiled correctly.
Check time-stamo of .class file.
Check permissions on folder/directory where class-files are getting generated.
Check if DrJAVA has appropriate permission on the directory.
Did you create a file, compiled it with out main?
Check class-path. Might be possible that previous class file is still being found by JDK in classpath.
Try compiling .java file from cmdLine instead of editor.
As others have mentioned, your code is fine. There must be a problem with your environment. I recently experienced a similar issue when investigating and answering this question.
Basically, in that question, the code Void.class instanceof Class resulted in a compiler error because a user-made Class.class existed in the classpath, so one Class (the Java built-in java.lang.Class) didn't match with the given Class (user-made).
Something similar may be at work here. It is possible that there is a user-made String.class in your classpath. Then in your main signature, String[] args would mean an array of your String, when Dr. Java must be looking for a main method taking an array of the Java built-in String, i.e. java.lang.String[]. If you have a custom String class in your classpath (or in your project?), then the Java compiler will choose it over the built-in String. If you were to compile and run your Test class from the command line, then you would get the runtime error: Exception in thread "main" java.lang.NoSuchMethodError: main.
Following #S0urceC0ded's suggestion, you may find this when looking at Test.class in a text editor:
main([LString;)V // A user-made String class
instead of what it's supposed to be:
main([Ljava/lang/String;)V // The built-in java.lang.String class
If so, remove your own String class (at least the .class file, but also the .java file so the .class file isn't re-created) from the classpath, and compile and run your Test class again.
Without a look at your environment, I can't tell for sure that this is the issue. But it can explain it.
If you are using Dr.Java as IDE, then you need to make sure that the main class containing 'public static void main' should be at the very top of your program. Otherwise Dr.Java throws this error during runtime.

can I load user packages into eclipse to run at start up and how?

I am new to java and to the eclipse IDE.
I am running Eclipse
Eclipse SDK
Version: 3.7.1
Build id: M20110909-1335
On a windows Vista machine.
I am trying to learn from the book Thinking in Java vol4.
The author uses his own packages to reduce typing. However the author did not use Eclipse and this is where the problem commes in..
This is an example of the code in the book.
import java.util.*;
import static net.mindview.util.print.*;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world");
print("this does not work");
}
this is the contents of print.Java
//: net/mindview/util/Print.java
// Print methods that can be used without
// qualifiers, using Java SE5 static imports:
package net.mindview.util;
import java.io.*;
public class Print {
// Print with a newline:
public static void print(Object obj) {
System.out.println(obj);
}
// Print a newline by itself:
public static void print() {
System.out.println();
}
// Print with no line break:
public static void printnb(Object obj) {
System.out.print(obj);
}
// The new Java SE5 printf() (from C):
public static PrintStream
printf(String format, Object... args) {
return System.out.printf(format, args);
}
} ///:~
The error I get the most is in the statement.
Import static net.mindview.util.print.*;
On this staement the Eclipse IDE says it cannot resolve net
also on the
print("this does not work");
The Eclipse IDE says that the class print() does not exist for the class HelloWorld.
I have been trying to get these to work, but with only limited success, The autor uses another 32 of these packages through the rest of the book.
I have tried to add the directory to the classpath, but that seems to only work if you are using the JDK compiler. I have tried to add them as libraries and i have tried importing them into a package in a source file in the project. I have tried a few other things but cant remember them all now.
I have been able to make one of the files work, the print.java file I gave the listing for in this message. I did that by creating a new source folder then making a new package in that foldeer then importing the print.java file into the package.
But the next time I try the same thing it does not work for me.
What I need is a way to have eclipse load all these .java files at start up so when I need them for the exercises in the book they will be there and work for me, or just an easy way to make them work everytime.
I know I am not the only one that has had this problem I have seen other questions about it on google searches and they were also asking about the Thinking In Java book.
I have searched this site and others and am just not having any luck.
Any help with this or sugestions are welcome and very appreciated.
thank you
Ok I have tried to get this working as you said, I have started a new project and I removed the static from the import statement, I then created a new source folder, then I created a new package in the source folder. Then I imported the file system and selected the the net.mindview.util folder.
Now the immport statement no longer gives me an error. But the the print statement does, the only way to make the print statement work is to use its fully qualified name. Here is the code.
import net.mindview.util.*;
public class Hello2 {
public static void main(String[] args) {
Hello2 test = new Hello2();
System.out.println();
print("this dooes not work");
net.mindview.util.Print.print("this stinks");
}
}
The Error on the print statement is:
The method print(String) is undefined for the type Hello2
and if I try to run it the error I get is:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method print(String) is undefined for the type Hello2
at Hello2.main(Hello2.java:6)
The Statement::::: net.mindview.util.Print.print("this stinks") is the fully qualified print statement and it does not throw an error but it does totally defeat the purpose of the print.java file..
If you have any questions please ask Ill get back to you as soon as I can.
I've had similar issues. I solved it by following the steps below:
Click File->New->Java Project. Fill in UtilBuild for the ProjectName. Chose the option "Use project folder as root and click 'Finish'.
Right-click on UtilBuild in the PackageExplorer window and click New->package. For the Package Name, fill in net.mindview.util
Navigate within the unzipped Thinking In Java (TIJ) folder to TIJ->net\mindview\util. Here you will find all the source code (.java) files for util.
Select all the files in the net\mindview\util folder and drag them to the net.mindview.util package under UtilBuild in Eclipse. Chose the 'Copy Files' option and hit 'OK'.
You will probably already have the 'Build Automatically' option checked. If not, go to Project and click 'Build Automatically'. This will create the .class files from the .java source files.
In Eclipse, right-click on the project you were working on (the one where you couldn't get that blasted print() method to work!) Click Properties and Java Build Path->Libraries. Click 'Add Class Folder...' check the box for UtilBuild (the default location for the .class files).
I think the confusion here arises due to CLASSPATH. If you use Eclipse to build and run your code then Eclipse manages your CLASSPATH. (You don't have to manually edit CLASSPATH in the 'Environment Variables' part of your computer properties, and doing so changes nothing as far as Eclipse Build and Run are concerned.)
In order to call code that exists outside your current project (I will name this 'outside code' for convenience) you need to satisfy three things:
A. You need to have the .class files for that code (as .class files or inside a JAR)
B. You need to indicate in your source code where to look for the 'outside code'
C. You need to indicate where to start looking for the 'outside code'
In order to satisfy these requirements, in this example we:
A. Build the project UtilBuild which creates the .class files we need.
B. Add the statement import static net.mindview.util.Print.*; in our code
C. Add the Class Folder library in Eclipse (Java Build Path->Libraries).
You can investigate the effect of Step C by examining the .classpath file that lives directly in your project folder. If you open it in notepad you will see a line similar to the following:
<classpathentry kind="lib" path="/UtilBuild>
You should combine this with your import statement to understand where the compiler will look for the .class file. Combining path="/UtilBuild" and import static net.mindview.util.Print.*; tells us that the compiler will look for the class file in:
UtilBuild/net/mindview/util
and that it will take every class that we built from the Print.java file (Print.*).
NOTE:
There is no problem with the keyword static in the statement
import static net.mindview.util.Print.*;
static here just means that you don't have to give specify the class name from Print.java, just the methods that you want to call. If we omit the keyword static from the import statement, then we would need to qualify that print() method with the class it belongs to:
import net.mindview.util.Print.*;
//...
Print.print("Hello");
which is slightly more verbose than what is achieved with the static import.
OPINION:
I think most people new to Java will use Eclipse at least initially. The Thinking in Java book seems to assume you will do things via command line (hence it's guidance to edit environment variables in order to update CLASSPATH). This combined with using the util folder code from very early in the book I think is a source of confusion to new learners of the language. I would love to see all the source code organised into an Eclipse project and available for download. Short of that, it would be a nice touch to include the .class files in just the 'net/mindview/util' folder so that things would be a little easier.
U should import package static net.mindview.util not static net.mindview.util.Print
and you should extend the class Print to use its method.......
You should remove the static keyword from your import decleration, this: import static net.mindview.util.print.*; becomes this: import net.mindview.util.print.*;
If that also does not work, I am assuming you did the following:
Create your own project;
Start copying code directly from the book.
The problem seems to be that this: package net.mindview.util; must match your folder structure in your src folder. So, if your src folder you create a new package and name it net.mindview.util and in it you place your Print class, you should be able to get it working.
For future reference, you should always make sure that your package decleration, which is at the top of your Java class, matches the package in which it resides.
EDIT:
I have seen your edit, and the problem seems to have a simple solution. You declare a static method named print(). In java, static methods are accessed through the use of ClassName.methodName(). This: print("this dooes not work"); will not work because you do not have a method named print which takes a string argument in your Hello2 class. In java, when you write something of the sort methodName(arg1...), the JVM will look for methods with that signature (method name + parameters) in the class in which you are making the call and any other classes that your calling class might extend.
However, as you correctly noted, this will work net.mindview.util.Print.print("this stinks");. This is because you are accessing the static method in the proper way, meaning ClassName.methodName();.
So in short, to solve your problem, you need to either:
Create a method named print which takes a string argument in your Hello2 class;
Call your print method like so: Print.print("this stinks");
Either of these two solutions should work for you.
In my case I've dowloaded and decompressed the file TIJ4Example-master.zip. in eclipse workspace folder. The three packages : net.mindview.atunit, net.mindview.simple and net.mindview.util are in this point of the project :
and java programs runs with no problems (on the right an example of /TIJ4Example/src/exercises/E07_CoinFlipping.java)

Categories