Java/reflection - where's error? - java

I found some posts about java/reflection on this site. But still can't understand something. Could anyone tell where's error in my code? (need to print "HELLO!")
Output:
java.lang.NoSuchMethodException: Caller.foo()
Here's my Main.java:
import java.lang.reflect.*;
class Main {
public static void main(String[] args) {
Caller cal = new Caller();
Method met;
try {
met = cal.getClass().getMethod("foo", new Class[]{});
met.invoke(cal);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
class Caller {
void foo() {
System.out.println("HELLO!");
}
}

getMethod() only finds public methods. Either change the access modifier of the Caller#foo() method to public, or use getDeclaredMethod() instead.

import java.lang.reflect.*;
public static void main(String[] args) {
public static void main(String[] args) {
try {
Class c = Class.forName("Caller");
Object obj = c.newInstance();
Method m = c.getMethod("foo");
m.invoke(obj);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
public class Caller {
public void foo() {
System.out.println("HELLO!");
}
}

Related

How to define a Java function to acception a function

I have a requirement of exception handling for all methods, suppose that I have a project and within the project, the StaleStateException is thrown, and I need to handle it, I want to do it like this:
class Util() {
public static void handle(XXXX method) {
try{
//invoke method
} catch(StaleStateException e) {
//do something
}
}
}
How can I implement this method?
Here is another way to do this:
public class Methods {
public static void someMethodToPass(String s){
System.out.println("Invoked, Here is the argument: " + s);
}
public static void invokerMethod(Method m) throws InvocationTargetException, IllegalAccessException {
m.invoke(null,"Some argument");
}
public static void main(String[] args) {
try {
invokerMethod(Arrays.stream(Methods.class.getMethods()).filter(m -> m.getName().equals("someMethodToPass")).findFirst().get());
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
Function<InputType, Void> = input -> {
// do stuff
System.out.println(input.toString());
}
class Util() {
public static void handle(Function<InputType, Void> method) {
try{
input.apply(input);
} catch(StaleStateException e) {
//do something
}
}
}

How to rewrite main class as a Public Void method to be called from another class

I have written my program around the main MonopolyGame.java game class - however - I am adding features such as splash screens etc; and I would like to call each of these from a separate class (RunFile.java) . How do I rewrite the following part of my main class so that it can be called from the RunFile.java. When I try to do this I get the following error:
The method MonopolyGame() is undefined for the type MonopolyGame
MonopolyGame.java
public class MonopolyGame extends JFrame{
// PRIVATE STATIC/DECLARATIONS ARE HERE
public static void main(String[] args) throws Exception {
{
//THIS IS WHERE I USED TO CALL THE SPLASH SCREEN
// SplashScreen s = new SplashScreen(8000);
// s.Splash();
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MonopolyGame window = new MonopolyGame();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}}
/**
* Create the application.
*/
public MonopolyGame()
{
try {
initialize();
for(int i = 0; i < 41 ; i++)
{
properties[i]=new Props();
}
setProperties();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public void initialize() throws InterruptedException {
//REST OF PROGRAM
RunFile.java
public class RunFile{
public static void main(String[] args)
{
SplashScreen s = new SplashScreen(8000);
s.Splash();
MonopolyGame m = new MonopolyGame();
m.MonopolyGame();
}
}
All you need to do is remove m.MonopolyGame(). Since it has the same name as the class, it is a Constructor and so when you do MonopolyGame m = new MonopolyGame(); it is running the logic inside of there so you don't need to do it again.
If you do want to call it separately, you should change the name of the method to something besides the classname (and add a return type such as void)
You don't need to rewrite the MonopolyGame() class, you can simply reflect the MonopolyGame() main method in your RunFile class.
public class RunFile {
public static void main(String[] args) {
Class<?> aClass = Class.forName(MonopolyGame.class.getName());
Method meth = aClass.getMethod("main", String[].class);
meth.invoke(null, (Object) args);
}
}

Ignore methods/void methods using EasyMock with Junit

"Added more details"
I want to Mock a certain void method but i'm not quite sure how to. I read about EasyMock but i don't know what to do when it's a void method, This is my main class;
Main class
public class Main {
Updater updater = new Updater(main.getID(), main.getName(),....);
try {
updater.updateContent(dir);
}
i want to mock updater.updateContent(dir); so that i can skip the try
Updater class
private String outD;
public void updateContent(final String outDir) throws Exception {
outD = outDir;
if (...) {
....;
}
}
... private void methods
This is my test class so far,
public class MainTest {
#Before
public void setUp() {
}
#Test
public void testMain() {
try {
try {
Updater updater = EasyMock.createNiceMock(Updater.class);
updater.updateContent("/out");
EasyMock.expectLastCall().andThrow(new RuntimeException());
EasyMock.replay(updater);
updater.updateContent("/out");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
(edited) thanks.
For methods returning void you must record the behavior this way:
Updater updater = EasyMock.createNiceMock(Updater.class);
updater.updateContent("someDir"); // invoke the easy mock proxy and
// after invoking it record the behaviour.
EasyMock.expectLastCall().andThrow(new RuntimeException()); // for example
EasyMock.replay(updater);
updater.updateContent("someDir"); // will throw the RuntimeException as recorded
Expect you have the following Main class
public class Main {
private Updater updater;
private int updatedContentCount; // introduced for the example
public Main(Updater updater) {
this.updater = updater;
}
public void updateContent() {
try {
updater.updateContent("/out");
updatedContentCount++;
} catch (Exception e) {
// skip for this example - normally you should handle this
}
}
public int getUpdatedContentCount() {
return updatedContentCount;
}
}
and your updater's API looks like this
public class Updater {
public void updateContent(String dir) throws Exception {
// do something
}
}
Then a test of the Main class would be something like this:
public class MainTest {
private Updater updater;
private Main main;
#Before
public void setUp() {
updater = EasyMock.createNiceMock(Updater.class);
main = new Main(updater);
}
#Test
public void testUpdateCountOnException() throws Exception {
updater.updateContent("/out");
EasyMock.expectLastCall().andThrow(new RuntimeException());
EasyMock.replay(updater);
main.updateContent();
int updatedContentCount = main.getUpdatedContentCount();
Assert.assertEquals(
"Updated count must not have been increased on exception", 0,
updatedContentCount);
}
}
The MainTest tests if the updateCount is handled correctly on an exception of the Updater.

Java - Using a static list from another class

I have a class like this , where I am updating a static variable in a thread. And I need to access this variable from another class.
import java.util.ArrayList;
import java.util.List;
public class VariableUpdater implements Runnable {
static List < String > abc = new ArrayList < String > ();
private static VariableUpdater instance = null;
private VariableUpdater() {}
public static synchronized VariableUpdater getInstance() {
if (instance == null) {
instance = new VariableUpdater();
}
return instance;
}
public static void main(String[] args) {
Thread th = new Thread( VariableUpdater.getInstance());
th.start();
}
#Override
public void run() {
while (true) {
System.out.println();
try {
abc.add("aa");
Thread.sleep(1000);
printContent();
} catch (Exception e) {
// TODO: handle exception
}
}
}
public synchronized void printContent() {
for (String string: abc) {
System.out.println(string);
}
}
}
And this variable needs to be accessed from another class like this :
public class Accessor {
public static void main(String[] args) {
VariableUpdater.getInstance().printContent();
}
}
The problem is, when running the Accessor class the list is empty.
Am I missing something here?
UPDATE/Solution
It turns out we can achieve this by using Hazelcast or some sort of messaging/caching utility. I will post a full solution soon.
Source: How to share object between java applications?
From this code u can access the List in another class object
import java.util.ArrayList;
import java.util.List;
public class VariableUpdater implements Runnable {
static List < String > abc = new ArrayList < String > ();
private static VariableUpdater instance = null;
private VariableUpdater() {}
public static synchronized VariableUpdater getInstance() {
if (instance == null) {
instance = new VariableUpdater();
}
return instance;
}
public static void main(String[] args) {
Thread th = new Thread(new VariableUpdater());
th.start();
Accessor.print();
}
#Override
public void run() {
for(int i=0;i<10;i++) {
System.out.println();
try {
abc.add("aa");
// Thread.sleep(1000);
//printContent();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public synchronized void printContent() {
System.out.println("List :: " + abc);
}
}
class Accessor {
public static void print() {
System.out.println("Accessor");
VariableUpdater.getInstance().printContent();
}
}
You have two main() methods in two different classes. On running two main() methods there will be two instances of JVM and those do not share anything. So your list will always be empty.
Use one main() method to start threads.
public class Main{
//shared state
public static void main(String[] args){
VariableUpdator variableUpdatorInstance = ...
Accessor accessorInstance = ...
variableUpdatorInstance.start();
accessorInstance.start();
//or in your case
new Thread(new VariableUpdater()).start();
Thread.sleep(9000); //runs eventually after 9 seconds
Accessor.print();
}
}
UPDATE:
class Thread1 extends Thread{
static List<String> list = new ArrayList<String>();
}
class OtherClass{
public void someMethod(){
Thread1.list; //this is how you access static variable of one class in other
}
}

Proper Error Handling in java

I need to know how to handle the exceptions in a situation like below. Please assist me,
public interface DCommand {
public Object execute(Class_A car);
}
public class Class_B {
public void getMessage() throws Exception {
throw new Exception("Test error");
}
}
public class Class_A {
Class_B cb = null;
public Class_B getClass_b() {
cb = new Class_B();
return cb;
}
public Object testAction(DCommand command) {
Object returnObject = null;
try {
return (Boolean) command.execute(this);
} catch (Exception e) {
System.out.println("ERROR IN CLASS B" + e.getLocalizedMessage());
}
return returnObject;
}
}
====================== simiulating ============================
public class Test {
public static void main(String[] args) {
Class_A c = new Class_A();
boolean a = (Boolean) c.testAction(new DCommand() {
#Override
public Object execute(Class_A car) {
try {
car.getClass_b().getMessage();
return true;
} catch (Exception ex) {
System.out.println("Error in the simulator.");
}
return false;
}
});
}
}
When I run the above code I need to catch the exception thrown by the Class_B in the Class_A where prints the "ERROR IN CLASS A".
Problem is that you are throwing a type of Exception in your Class B's getMessage method. Instead you should define your own exception by extending java.lang.Exception.
public class ClassBException extends Exception {
public ClassBException(String msg) {
super(msg);
}
}
And then use ClassBException to be thrown in Class B's getMessage method like this
public class Class_B {
public void getMessage() throws ClassBException {
throw new Exception("Test error");
}
}
Now you need to a have separate catch block for ClassBException at any place you are calling Class B's getMessage method.
Add this Methode to class A:
public void runGetMessage()
{
try{
cb.getMessage();
}catch(Exception e){
System.out.println("Error in CLASS A.");
}
}
And change the Execute methode to:
public Object execute(Class_A car) {
try {
car.getClass_b();
car.runGetMessage();
return true;
} catch (Exception ex) {
System.out.println("Error in the simulator.");
}
return false;
}

Categories