I am referring to my previous question but this time I used the java compiler and the compiler compiles the output- it gives a weird output. And this time I used this instead of super.
This is the code of the program.
class Con {
int x = 10;
Con() {
this(2);
System.out.println("x :" + x);
}
Con(int i) {
x = i;
System.out.println("x :" + x);
}
}
class DemoCon {
public static void main(String args[]) {
Con c1 = new Con();
}
}
What do you think is the problem here? Is this a bug in Java?
Java version - 1.6.0 JDK
I used Eclipse to run the program and there is a Class not found exception.
A.java is the file name... We did a minor edit and made a public class called A.java too but the results are same. We further found out that the problem lies in the compiler.
On Windows it seems CON is reserved name and cannot be used for folders/directories or filenames.
The following
print "test" > Con.java
is not working.
Therefor the compiler is unable to create your Con.class and crashes.
From MSDN:
Do not use the following reserved device names for the name of a file:
CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. Also avoid these names followed immediately by an extension; for example, NUL.txt is not recommended
perhaps the problem exists because CON is a reserved file name (it was on MS-DOS -- see http://support.microsoft.com/kb/31157 http://www.computerhope.com/copyhlp.htm)
How did you compile it? On Win7 32b with Java 1.6 I get:
Type name is not valid. 'Con' is an invalid name on this platform.
Yes it looks like a bug. It compiled very well on my
Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)
environment on Mac OS X.
Maybe we can help further if you tell us whether you are using Sun (Oracle) JDK or OpenJDK?
Problem might be about class name (Con) and file name (A) are different (they should be the same) and you have two classes at the same level in a single file. Anyway, it compiles well on my box.
In java, the class name and file name must be exactly the same. In your case, your class name is Con, therefore, your class file must be Con.java. Since DemoCon is your class with the static void main(String[] args), your java file must be DemoCon.java.
I saved your code as DemoCon.java .
and ran it as
javac DemoCon.java
java DemoCon
o/p was
x :2
x :2
Related
I'm playing with Java 15's new records feature, and how it interacts with reflection. I've run into some strange behaviour, where I can sometimes access a record's constructor via reflection, and sometimes not. For example, given the following Java file:
Recording.java:
public class Recording {
public static void main(String[] args) {
System.out.println("Constructors: " + MainRecord.class.getConstructors().length);
System.out.println("Methods: " + MainRecord.class.getDeclaredMethods().length);
}
record MainRecord(int i, String s) {}
}
This behaves as follows:
❯ javac --enable-preview --release 15 Recording.java
Note: Recording.java uses preview language features.
Note: Recompile with -Xlint:preview for details.
❯ java --enable-preview Recording
Constructors: 0
Methods: 5
In other words, the call to getConstructors() does not find any constructors (while the call to `getDeclaredMethods() does find methods). I don't understand why not, because the constructor does exist:
❯ javap Recording\$MainRecord
Compiled from "Recording.java"
final class Recording$MainRecord extends java.lang.Record {
Recording$MainRecord(int, java.lang.String);
public final java.lang.String toString();
public final int hashCode();
public final boolean equals(java.lang.Object);
public int i();
public java.lang.String s();
}
(Putting the record in a separate Java file gives the same results.)
However, if I do the same from JShell:
❯ jshell --enable-preview
| Welcome to JShell -- Version 15
| For an introduction type: /help intro
jshell> record JShellRecord(int i, String s) {}
| created record JShellRecord
jshell> JShellRecord.class.getConstructors().length
$2 ==> 1
So, now it does find the constructor.
Here's the Java version I'm using:
❯ java -version
openjdk version "15" 2020-09-15
OpenJDK Runtime Environment AdoptOpenJDK (build 15+36)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 15+36, mixed mode, sharing)
Compiling and running the same program from Java 14 does work:
❯ java -version
openjdk version "14.0.2" 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.2+12)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.2+12, mixed mode, sharing)
❯ javac --enable-preview --release 14 Recording.java
Note: Recording.java uses preview language features.
Note: Recompile with -Xlint:preview for details.
❯ java --enable-preview Recording
Constructors: 1
Methods: 5
I know that in Java 15, compared to Java 14, a number of restrictions have been put in place regarding reflection on records, but if I read the JEP correctly, those only apply to modification. Finding (and perhaps invoking) a constructor does not seem to apply.
Can anyone tell my what's going on here? What do I need to do to see a record's constructor in Java 15 through reflection?
getConstructors() returns public constructors only. Use getDeclaredConstructors() to get all constructors.
Your declaration record MainRecord(int i, String s) {} lacks the public modifier, so it creates a non-public class and also a non-public constructor. See JLS15-preview, §8.10.4
The implicitly declared canonical constructor has the same access modifier as the record class R, unless the record class lacks an access modifier, in which case the canonical constructor has package access
This does indeed differ from the JDK 14 preview. The beginning of the JDK 15 preview document says:
The changes are the same as those in the first preview of Records in Java SE 14, except for the following:
…
8.10.4 Removed requirement that canonical constructor must be public. Any access modifier must provide at least as much access as the record class. If a canonical constructor is implicitly declared, then its access modifier is the same as the record class.
It seems, top level classes created in JShell are implicitly public.
> jdk-15\bin\jshell --enable-preview
| Welcome to JShell -- Version 15
| For an introduction type: /help intro
jshell> record JShellRecord(int i, String s) {}
| created record JShellRecord
jshell> JShellRecord.class.getConstructors()[0]
$2 ==> public JShellRecord(int,java.lang.String)
jshell> java.lang.reflect.Modifier.isPublic(JShellRecord.class.getModifiers())
$3 ==> true
jshell>
I have created a simple program to practice polymorphism and inheritance, and it compiles and runs perfectly in a single file. I then split the program into multiple files all in the same package. I was able to compile the files using javac *.java, and it compiled without errors. However when I run the program by typing java zoo_sim i get:
Error: Could not find or load main class zoo_sim Caused by:
java.lang.NoClassDefFoundError: zoo_proj/zoo_sim (wrong name: zoo_sim)
The name of the class containing main is zoo_sim.
The name of the package is zoo_proj.
At the top of each file I have the line:
package zoo_proj;
I am new to java so I'm sorry if I'm missing something stupid here.
Thanks!
Edit: here is my zoo_sim class:
package zoo_proj;
public class zoo_sim {
public static void main(String args[]) {
//create and allocate animal array
Animal animalArray[] = new Animal[3];
//and Leo to animal array
Animal Leo = new Cat("Leo", 4, 13);
animalArray[0] = Leo;
//add Crixus to animal array
Animal Crixus = new Dog("Crixus", 5, 50);
animalArray[1] = Crixus;
//add Peter to animal array
Animal Peter = new Pig("Peter", 3, 100);
animalArray[2] = Peter;
//c style for loop
for(int i = 0; i < animalArray.length; i++) {
System.out.print(animalArray[i].getName() + " is " + animalArray[i].getAge() + " years old and says ");
animalArray[i].makeSound();
}
//print line in between
System.out.println();
//for each style for loop
for(Animal i : animalArray) {
System.out.print(i.getName() + " weighs " + i.getWeight() + " pounds and says ");
i.makeSound();
}
}
}
I'm using linux running in the command line. Here is my output for java -version:
openjdk version "11.0.3" 2019-04-16
OpenJDK Runtime Environment (build 11.0.3+7-Ubuntu-1ubuntu218.04.1)
OpenJDK 64-Bit Server VM (build 11.0.3+7-Ubuntu-1ubuntu218.04.1, mixed mode, sharing)
when I type java zoo_proj.zoo_sim I get:
Error: Could not find or load main class zoo_proj.zoo_sim
Caused by: java.lang.ClassNotFoundException: zoo_proj.zoo_sim
I think your problem is that you're executing java zoo_proj.zoo_sim from within the package directory zoo_proj.
Go one level up and execute java zoo_proj.zoo_sim from the directory one above from zoo_proj.
My steps to reproduce are:
Let my top directory be /zoo.
All files of package zoo_proj are within /zoo/zoo_proj directory,
i.e. the layout is:
/zoo
----/zoo_proj
-------------/Animal.java
-------------/Cat.java
-------------/Dog.java
-------------/Pig.java
-------------/zoo_sim.java
All commands are executed while being in /zoo directory, NOT in zoo/zoo_proj.
To compile java files, execute javac zoo_proj/*.java. On successful execution, zoo_proj should now contain corresponding .class file for each .java file.
Execute java zoo_proj.zoo_sim. Program executes successfully.
If you go to /zoo/zoo_proj and execute java zoo_proj.zoo_sim from here, the output is Error: Could not find or load main class zoo_proj.zoo_sim.
When I try to load the Nashorn compatibility file for Rhino (load("nashorn:mozilla_compat.js")) it comes up with the following error:
java.lang.RuntimeException: javax.script.ScriptException: ReferenceError: "net" is not defined in nashorn:mozilla_compat.js at line number 67
I've tried everything to get it to work but nothing has helped :(
This can happen if your script (not mozilla_compat.js itself) contains a declaration with a qualified name like this:
var x = new net.yourdomain.yourpackage.ClassName();
instead of doing
importPackage(Packages.net.yourdomain.yourpackage);
var x = new ClassName();
The former works in Rhino, but not in Nashorn, even with the compatibility script. The latter however will work in both environments.
I ran the following code with the latest JDK 8 update released (8u60) - available for download # http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
import javax.script.*;
public class Main {
public static void main(String[] ar) throws Exception {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByName("nashorn");
e.eval("load('nashorn:mozilla_compat.js')");
// this should print 'function' and mozilla_compat.js defines that function
e.eval("print(typeof importClass)");
}
}
And it printed "function" as expected. I checked it on jdk9-dev tip forest build as well. It works with that version as well. Will you please print "java -version" and make sure you're using recent JDK 8 ?
I'm looking for a way to check which java version my software is running under.
I'd like to verify during load time my software is running on at least
To get the java version you can use any of these depending on the version you want:
java.specification.version
java.version
java.vm.version
java.runtime.version
However, note that java versions are not equivalent between operative systems. So Java 6 on OSX does not mean the same thing as Java 6 on Windows. So, I would recommend you to also get the OS where the application is running, if you wish to determine if a given feature is available:
System.getProperty("os.name")
As a general guideline, all of this stuff is in the System package. A trick I use is iterate through all the available fields to have an idea of what I can use:
import java.util.Map;
class ShowProperties {
public static void main(String[] args) {
for (Map.Entry<Object, Object> e : System.getProperties().entrySet()) {
System.out.println(e);
}
}
}
Use java.version property to retrieve the jre version.
String javaVersion = System.getProperty("java.version");
if ((!javaVersion.startsWith("1.6")) && (!javaVersion.startsWith("1.7")) && (!javaVersion.startsWith("1.8")) && (!javaVersion.startsWith("1.9")))
{
// error
}
You can use System.getProperty:
System.out.println(System.getProperty("java.version"));
1.7.0_21
java.lang.System.getProperty("java.version")
I want to use JOMP API (equivalent to OpenMP in C) but I met some problems:
This is the code I want to run:
import jomp.runtime.*;
public class Hello
{
public static void main (String argv[])
{
int myid;
//omp parallel private(myid)
{
myid = OMP.getThreadNum();
System.out.println("Hello from " + myid);
}
}
}
It is just an hello worl but I have a problem with the compiler. Please have a quick look at this page to understand:
http://www2.epcc.ed.ac.uk/computing/research_activities/jomp/download.html
But I can't, I do not understand how it works... I can only compile it with eclipse default compiler (I guess) and then I have only one thread!
I understand I have to compile this code (in a .jomp file) with
java jomp.compiler.Jomp MyFile
and then compile normally but I can't do this in ecplise neither in the terminal (I do not know how to install this compiler!)
ps: I use Ubuntu 12.04 on a Intel® Core™ i7-3610QM CPU # 2.30GHz × 8.
You just need to add the JOMP parameters to your launch configuration, this example can help you:
JOMP eclipse workaround