While I am using reflection I came upon this error. I have a class named Test1, and when I try to get a Class object of it by entering test1 as input to Class.forName() it generates LinkageError instead of ClassNotFoundException. Why does the lower-case letter confuse the program and prevent it from generating the usual ClassNotFoundException as with for example "sjghdjgh"?
Minimal example
Main
public class Main {
public static void main(String[] args) {
try {
Class.forName("test1");
}
catch (ClassNotFoundException cnfe) {
System.out.println(cnfe.toString());
}
catch (LinkageError le) {
System.out.println(le.toString());
}
}
}
Test1
public class Test1 {
}
If you ask some file systems for test1.class they will give you back a Test1.class instead of a file-not-found (because they are case-insensitive) and then that class file does not contain a class called test1, but instead a Test1 (Java class names are case-sensitive), so that the classloader errors out.
This is rarely a problem in practice, because most applications are deployed using Jar files (so that there are no individual files for the classes in the filesystem).
Related
File Name = multiple_main_methods.java
class multiple_main_methods_two {
public static void main(String[] args){
System.out.println("Class second");
}
}
class multiple_main_methods_one {
public static void main(String[] args){
System.out.println("Class first");
}
}
Output
Class first
IDE used - IntelliJ IDEA
IntelliJ is choosing a class to execute.
Remember, you execute the main method in a class, not in a file.
Check it in your Run configurations
enter image description here
It is not giving error because your main methods belong to different classes i.e. multiple_main_methods_two and multiple_main_methods_one which is completely fine.
package abc ;
class Trying
{
Trying ()
{
System.out.println("hello");
}
}
public class trying {
public static void main(String[] args) {
new Trying () ;
}
}
In this when I change the name of class from Trying to some other name it works , but here it says :
Error: Could not find or load main class abc.trying
/Users/name/Library/Caches/NetBeans/8.2/executor-snippets/run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)
Why is this happening ?
I didn't find such case in any of the questions already asked .
Java is case sensitive language, but there is no documentation that class name should be case sensitive or not.
In eclipse it will show you syntax error
Class file collision: A resource exists with a different case:
'/sample/bin/abc/Trying.class'.
OR
If not shows error it will create class file of only one class either Trying or trying.
1)
If class file of Trying class is generated then It will throw
Error: Main method not found in class abc.trying
Since there is no main method in class Trying, And at runtime it looking for main method to start.
2)
If class file of trying class is generated then It will throw
Exception in thread "main" java.lang.NoClassDefFoundError:
here at runtime it looking for class Trying since it called in main of class trying. It fails to load coz its not compiled.
So we can conclude java not allow two class with sameName even different case
more details of case sensitive of class name is here
class Trying
{
Trying ()
{
System.out.println("hello");
}
}
public class Try_Main {
public static void main(String[] args) {
new Trying () ;
}
}
Please use two different class names other than same name with different cases. On compilation, the compilation will success and compile will create two class files with same name but different cases. But, the OS only allows a single file and it simply overwrites first one( which created firstly on compilation, then second) by the second one. On running, you will get a run time error, because one of the classes is missing. So, please use different names...
Well, this class should be public and be sure of saving the file name as the class Name
You have specified Trying multiple times.
package abc;
public class Trying {
public static void main(String[] args) {
trying1();
}
public static void trying1() {
System.out.println("Good?!");
}
}
Constraints:
I have a maven source code generator that I wrote that is creating POJO classes
from some data files that have nested namespaces. I want each namespace to
be nested as an inner class. In some cases out of my control I end up
with inner classes that are the same simple name as the outermost
class.
All the classes must be public scope as this is for a type safe
wrapper over something like a properties file, but hierarchical..
I can't change the names otherwise I am changing the names meaning and the namespace
that is enclosing data.
Given than I have the following code:
public class A
{
public class B
{
public class A
{
}
}
}
Inner classes should append the name of the outer class to form a unique namespace such as A$B$A.class, I haven't found a valid reason for this not to compile.
Is there any trick to get this to compile?
No. From the JLS section on class declarations:
It is a compile-time error if a class has the same simple name as any of its enclosing classes or interfaces.
Note: I somehow managed to miss this on my first pass through looking for an explicit rule. Check the edit history if you want the tortuous way I got here.
You asked: Is there any trick to get this to compile?.
The answer is: Well, maybe....
Create a class like the following:
public class A
{
public class B
{
public class X
{
}
}
}
And a class where this class is going to be used
public class AUse
{
public static void main(String[] args)
{
A.B.X aba = new A().new B().new X();
System.out.println("Created "+aba+" of class "+aba.getClass());
}
}
Then, download the Apache Byte Code Engineering Library (BCEL), and create and run the following class:
import java.io.FileOutputStream;
import org.apache.bcel.Repository;
import org.apache.bcel.util.BCELifier;
public class CreateCreators
{
public static void main(String[] args) throws Exception
{
new BCELifier(
Repository.lookupClass("A"),
new FileOutputStream("ACreator.java")).start();
new BCELifier(
Repository.lookupClass("A$B"),
new FileOutputStream("A$BCreator.java")).start();
new BCELifier(
Repository.lookupClass("A$B$X"),
new FileOutputStream("A$B$XCreator.java")).start();
new BCELifier(
Repository.lookupClass("AUse"),
new FileOutputStream("AUseCreator.java")).start();
}
}
This uses the BCELifier class from the BCEL. This is a class that takes a .class file, and creates a .java file that can be compiled to a .class file, that, when it is executed, creates the .class file that it was originally fed with. (Side note: I love this library).
So the A$B$XCreator.java file that is created there contains the BCEL code that is necessary to create the A$B$X.class file. This consists of statements like the generation of the constant pool and the instructions:
...
_cg = new ClassGen("A$B$X", "java.lang.Object", "A.java",
ACC_PUBLIC | ACC_SUPER, new String[] { });
...
il.append(_factory.createFieldAccess("A$B$X", "this$1",
new ObjectType("A$B"), Constants.PUTFIELD));
Similarly, the AUseCreator.java contains the BCEL code that creates the AUse.class. For example, the instruction of the constructor invocation of `A$B$X':
...
il.append(_factory.createInvoke("A$B$X", "<init>", Type.VOID,
new Type[] { new ObjectType("A$B") }, Constants.INVOKESPECIAL));
Now you can simply replace the String occurrences of "A$B$X" with "A$B$A" in the A$B$XCreator.java and AUseCreator.java, and then compile and run these classes.
The result will be a A$B$A.class file, and a AUse.class file that uses the A$B$A.class. Executing the AUse will print
Created A$B$A#15f5897 of class class A$B$A
I'm not sure whether this is considered as a "trick", or whether it still can be called "compiling" at all, but there is a way, at least. The key point is here, of course, that the fact that it did not compile is solely due to a limitation of the language, but there is no reason why this should not be representable in form of class files, regardless of how they are created.
You can't get it to compile, but more importantly, why would you need to?
What's wrong with:
public class A
{
public class B
{
public class InnerA
{
}
}
}
This seems like a design problem that you need to fix. If you can't rename it, consider anonymous inner classes. Or take some of those classes outside. Or just don't even use them.
It's a bit of a hack, but this compiles at my machine:
class A
{
public class B
{
public class Α
{
}
}
}
Try it. Literally: copy-past this thing ;)
SPOILER:
The name of the inner class is a capital letter alpha of the Greek alphabet. It's a Unicode character.
Depending on what you're after, the following might work for you:
public class A {
class B extends C {
}
public static void main(String[] args) {
new A().new B().new A();
}
}
class C {
class A {
{
System.out.println(getClass());
}
}
}
I thought this would be a trivial matter, but I can't seem to find a method similar to class_exists in Java. I'm writing a test to verify that a class name is defined. How can I replicate this in Java with jUnit?
<?php
$this->assertTrue(class_exists('Car'), 'Should have a class called "Car"');
TestCar.java
import org.junit.Assert;
import org.junit.Test;
public class TestCar {
#Test
public void testCarExists() {
try {
Class.forName("Car");
} catch(ClassNotFoundException e) {
Assert.fail("Should create a class called 'Car'.");
}
}
}
Car.java
public class Car {
// just enough :-)
}
One advantage of Java is that you have a compiler, so usually this is a non-issue. If you compile your code properly and then, for some reason, drop a required jar file from the runtime environment, you'll get a java.lang.ClassNotFoundException, so that should be enough.
If you want to be super-extra-safe, you could try calling Class.forName:
#Test
public void testClassExists {
try {
Class.forName("org.mypackage.Car");
} catch (ClassNotFoundException e) {
Assert.fail("should have a class called Car");
}
}
My objective is to read in to the command line the name of a Class I wish to observe info on. When I know the class name before runtime, I have no issue. What I can't seem to manage is how to create a class object based on a string input.
public class Tester {
static void methodInfo2(Object obj) throws ClassNotFoundException {
//some stuff
System.out.print("Test!");
}
public static void main (String args[]) throws ClassNotFoundException{
String className = args[0];
System.out.println("Class: "+className);
//myclass2 mc = new myclass2();
//Class c = mc.getClass();
Class argClass = Class.forName(className);
try {
methodInfo2(argClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
The 2 commented out lines in the main method show what I have done in the past when I know the class name before I compile. The following uncommented line shows what I thought should work, but I receive a ClassNotFoundException. The class certainly exists so I'm not sure what problem I'm having.
Two suggestions:
Make sure you're giving it the fully-qualified name (e.g. "java.lang.Thread" and not just "Thread").
Make sure the compiled class file is actually on the classpath.
Class.forName is the right way to load a class by name at runtime.
Either your argument is wrong or your class isn't in the classpath.