Main class
public class Main {
public static void main(String[] args) {
// Class load
A a = new A();
a.msg();
}
}
A class
public class A {
public void msg() {
System.out.println("msg");
}
}
I have written code in the main class that calls a msg() method of class A
After I created the jar file, I pull out A.class.
Then the path will have a jar file with missing A.class, and A.class.
A a = new A();
a.msg();
How do I dynamically load and run A.class without making any changes to the above code?
Please help me..
Looks like you want to load a class dynamically. I would recommend you to create a jar and load it using URIClassLoader. There is a really good answer here:- How should I load Jars dynamically at runtime?
A.class has to be in the classpath somewhere for the code to run. you can put it in a jar of its own, and add the second jar to the classpath. Then the class loader can find it.
Related
I'm stuck in service loader class(java) can anybody help, here is my code and pic attached with it.
see the pic to understand completely and tell me what's the issue
Interface Code
package ServiceLoader_.SL;
interface Account {
String getMessage();
}
Class implementing that interface
package ServiceLoader_.SL;
public class Message implements Account {
#Override
public String getMessage() {
return "Hello";
}
}
Main class
package ServiceLoader_.SL;
import java.util.ServiceLoader;
public class main {
public static void main(String[] args) {
ServiceLoader<Account> ac = ServiceLoader.load(Account.class);
Account ab = ac.iterator().next();
if(ac.iterator().hasNext()){
System.out.println("hay^");
}
}
}
Gives error that no such element found when trying to access ac.iterator().next()
Click HereTo See Image
As specified by the documentation of ServiceLoader, the provider-configuration file must be part of the classpath and for ServiceLoader<Account> will be resolved as
META-INF/services/ServiceLoader_.SL.Account
Based on what I can deduct from the image, your file seems to reside at
ServiceLoader_/META-INF/services/ServiceLoader_.SL.Account
which the ServiceLoader implementation is unaware of, thus it will not locate (and therefore not provide) the implementation class ServiceLoader_.SL.Message.
To fix this issue you must move the META-INF to the classpath root. Since I do not recognize the IDE shown in the image, I cannot say how one can do that though.
package concurrencyTest;
public class concurrencyTest implements Runnable
{
#Override
public void run()
{ System.out.println("Hello from a thread!"); }
public static void main(String[] args)
{
concurrencyTest c = new concurrencyTest();
Thread t = new Thread(c);
t.start();
}
}
Hi, I'm just trying to get my java concurrency test to run. But I'm getting this error :
Error: Main method not found in class concurrencytest.ConcurrencyTest, please
define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
I'm guessing that somewhere, in the myriad of project directories and subfiles that a java program needs to run, the name of the project or class has been wrongly referenced in lowercase letters. I've manually been thru all the files I can find that span from the root directory and renamed any instance of lowercase 'concurrencytest'. But still it seems the compiler finds a reference to lowercase concurrencytest and so refuses to compile. Any idea where this reference may be?
My root directory, source directory, and java code file are all called 'concurrencyTest'
edit
amended the original code for this question to include 'static' in the main method definition. Doing this was necessary but has not fixed the problem.
You wrote the main definition wrong. You should change it as below:
public static void main(String[] args) {
// ...
}
I found a reference to 'concurrencytest' in the meta file ...\concurrencyTest\nbproject\project.properties
So I changed it to 'concurrencyTest'
Also when NetBeans can't find the expected main method in the class it expects, it opens a 'RunProject' window where it lists main methods from classes it has found. For me it found a main in 'concurrencyTest' so I selected it.
One of these actions solved the problem, but not sure which one.
I encounter a interesting error by accident and I need you help me figure it out.
as for the below code every thing is ok:
public class HelloWorld{
public static void main(String[] args){
System.out.println("hello world");
}
}
then as for the follow code, something interesting come.
import junit.framework.TestCase;
public class HelloWorld extends TestCase{
public static void main(String[] args){
System.out.println("hello world");
}
}
when I run it, it says
cant find or load main class.
I know when jvm load HelloWorld class it will load TestCase class first. So I make the below code segment.
public class HelloWorld {
public static void main(String[] args) throws ClassNotFoundException{
Class.forName("junit.framework.TestCase");
}
}
Exception in thread "main" java.lang.ClassNotFoundException: junit.framework.TestCase
I dont know why? Maybe the TestCase class is not on my classpath ? But as for the second code segment I ensure TestCase is on my classpath.
So my question is:
Why can't I load TestCase class?
Why can't it find or load main class when extend TestCase class?
Note: I know the print helloworld function has nothing with TestCase class which used to junit test but I want to figure out the reason that bring this suprise.
I dont know why? Maybe the TestCase class is not on my classpath ? But
as for the second code segment I ensure TestCase is on my classpath.
Class.forName("junit.framework.TestCase");
returns the Class object associated with TestCase class. It doesn t set the classpath.
That's why you rise the exception :
Exception in thread "main" java.lang.ClassNotFoundException:
junit.framework.TestCase
You try to load a class which is not in the classpath.
To solve your problem with Eclipse, go in the properties windows of your project, then at the left, you have the Java Build Path option, go inside and look at the libraries tab. Here, you should add the JUnit library if you want JUnit to be in the classpath.
is there a way to declare 2 classes on the same .java file using Eclipse - also how the compiler will distinguish the .class for each declare class.
example
public class ThisTest
{
public static void main(String[] args)
{
}
}
class SimpleArray
{
}
thank you for your time.
is there a way to declare 2 classes on the same .java file using Eclipse
Yes, you can have several classes defined in a single .java file, but there may at most one public class in each file. (Just as in your example.)
Note that if you have a public class in a .java file, the name of that class must be the same as the name of the .java file.
how the compiler will distinguish the .class for each declare class.
The names of the .class files does not depend on the name of the .java file, but on the identifiers of the class declarations.
If you have
class A {}
class B {}
in a file named Classes.java, you'll get A.class and B.class if you compile it.
Yes, exactly like your example.
The extra class need to be non-public
You could also define inner/nested classes. In this case you should investigate the difference
Java inner class and static nested class
public class ThisTest
{
public static void main(String[] args)
{
}
static class SimpleArray
{
}
class SimpleArray2 {}
}
class Buddy {}
Each class will be located in an own .class file in a directory similar to the package.
Nested classes get its host prefixed and separated by an '$'.
The above case results in four class files
ThisTest.class
ThisTest$SimpleArray.class
ThisTest$SimpleArray2.class
Buddy.class
Just check the bin or classes folder of your eclipse project.
Assume, that I have class with static methods only. Will class loader load every imported class when loading class to memory? Or it will only load imports when a method from this would need access to it?
Question is whether class loader loads imports when the class is loaded to memory, or just before some methods want to use them.
If it is the first option I would probably need to divide some of my Util classes, to be more specialized.
I think you can test it as follows:
package pkg1;
public class Test {
static {
System.out.println("Hello 111");
}
public static void meth() {
System.out.println("Hello 222");
}
}
Test 1:
package pkg2;
import pkg1.Test;
public class Tester {
public static void main(String... args) {
Test t;
}
}
That prints nothing.
Test 2:
package pkg2;
import pkg1.Test;
public class Tester {
public static void main(String... args) {
Test.meth();
}
}
Prints:
Hello 111
Hello 222
So, just because you have imported a class does not mean the classloader will load the class into the memory. It loads it dynamically when it's used.
I don't claim to know a lot about the class loader, but if you're talking about import statements then the class loader is irrelevant.
Import statements exist purely to allow the developer to use short class names rather than the fully qualified name of each class referenced in the class being written. The compiler uses those import statements very early on to resolve the names of the referenced classes before a single line of bytecode is created.
In general, the static code block at the top of a class file with a report (i.e. a print statement ) will give you a good idea of when the loading happens in your particular application.
However, when dealing with corner cases, like dynamic classes, inner static classes, or classes off the classpath that are dynamically loaded, you will have to be careful - because these classes might actually be loaded MULTIPLE times in an application.