Reputation: 51
My current project is a JavaFX Application with RMI. Currently I have two three classes, which I'd like to reduce to two, but I am unable to find out how.
The three classes: StartClient.java BannerController.java AEXBanner.java
Codes and the errormessage:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389) at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767) Caused by: java.lang.IllegalStateException: Not on FX application thread; currentThread = main at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236) at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423) at javafx.stage.Stage.(Stage.java:241) at javafx.stage.Stage.(Stage.java:227) at client.BannerController.(BannerController.java:71) at client.BannerController.main(BannerController.java:174) ... 11 more Exception running application client.BannerController D:\Dropbox\HBO ICT\Leerjaar 2\GSO3\AEXBanner Week 1\nbproject\build-impl.xml:1051: The following error occurred while executing this line: D:\Dropbox\HBO ICT\Leerjaar 2\GSO3\AEXBanner Week 1\nbproject\build-impl.xml:805: Java returned: 1 BUILD FAILED (total time: 17 seconds)
Upon starting the program with StartClient (whilst the RMI server is running) everything works fine. But when I directly start the application with the BannerController class, Netbeans gives me the error posted above.
I am 100% sure the RMI server works fine, so no need to worry about that.
The three classes can be found below:
StartClient:
package client;
import javafx.application.Application;
import javafx.stage.Stage;
/**
*
* @author Max
*/
public class StartClient extends Application {
@Override
public void start(Stage primaryStage) {
BannerController.main(null);
}
public static void main(String[] args) {
launch(args);
}
}
BannerController: package client;
/**
*
* @author Max
*/
import shared.IEffectenBeurs;
import shared.IFonds;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.stage.Stage;
public class BannerController extends Application {
private AEXBanner banner;
private IEffectenBeurs effectenbeurs;
private Timer pollingTimer;
private String bindingName = "Effectenbeurs";
private Registry registry = null;
private static boolean locateRegistry = true;
public BannerController(String ip, int port) {
banner = new AEXBanner();
pollingTimer = new Timer();
System.out.println("Client: IP Address: " + ip);
System.out.println("Client: Port number " + port);
if (locateRegistry) {
// Locate registry at IP address and port number
registry = locateRegistry(ip, port);
// Print result locating registry
if (registry != null) {
printContentsRegistry();
System.out.println("Client: Registry located");
} else {
System.out.println("Client: Cannot locate registry");
System.out.println("Client: Registry is null pointer");
}
if (registry != null) {
effectenbeurs = bindEffectenbeursUsingRegistry();
}
} else {
// Bind fonds using Naming
effectenbeurs = bindEffectenbeursUsingNaming(ip, port);
}
if (effectenbeurs != null) {
System.out.println("Client: Effectenbeurs bound");
} else {
System.out.println("Client: Effectenbeurs is null pointer");
}
banner.start(new Stage());
pollingTimer.schedule(new TimerTask() {
@Override
public void run() {
try {
StringBuilder sb = new StringBuilder();
for (IFonds f : effectenbeurs.getKoersen()) {
sb.append(f.toString() + " ");
}
System.out.println(sb.toString());
banner.setKoersen(sb.toString());
} catch (RemoteException ex) {
Logger.getLogger(BannerController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}, 0, 2000);
}
// Print contents of registry
private void printContentsRegistry() {
try {
String[] listOfNames = registry.list();
System.out.println("Client: list of names bound in registry:");
if (listOfNames.length != 0) {
for (String s : registry.list()) {
System.out.println(s);
}
} else {
System.out.println("Client: list of names bound in registry is empty");
}
} catch (RemoteException ex) {
System.out.println("Client: Cannot show list of names bound in registry");
System.out.println("Client: RemoteException: " + ex.getMessage());
}
}
private IEffectenBeurs bindEffectenbeursUsingRegistry() {
IEffectenBeurs effectenbeurs1 = null;
try {
Object object = registry.lookup(bindingName);
effectenbeurs1 = (IEffectenBeurs) registry.lookup(bindingName);
} catch (RemoteException ex) {
System.out.println("Client: Cannot bind Effectenbeurs");
System.out.println("Client: RemoteException: " + ex.getMessage());
effectenbeurs1 = null;
} catch (NotBoundException ex) {
System.out.println("Client: Cannot bind Effectenbeurs");
System.out.println("Client: NotBoundException: " + ex.getMessage());
effectenbeurs1 = null;
}
return effectenbeurs1;
}
private Registry locateRegistry(String ipAddress, int portNumber) {
Registry registry = null;
try {
registry = LocateRegistry.getRegistry(ipAddress, portNumber);
} catch (RemoteException ex) {
System.out.println("Client: Cannot locate registry");
System.out.println("Client: RemoteException: " + ex.getMessage());
registry = null;
}
return registry;
}
private IEffectenBeurs bindEffectenbeursUsingNaming(String ipAddress, int portNumber) {
IEffectenBeurs Effectenbeurs = null;
try {
Effectenbeurs = (IEffectenBeurs) Naming.lookup("rmi://" + ipAddress + ":" + portNumber + "/" + bindingName);
} catch (MalformedURLException ex) {
System.out.println("Client: Cannot bind Effectenbeurs");
System.out.println("Client: MalformedURLException: " + ex.getMessage());
Effectenbeurs = null;
} catch (RemoteException ex) {
System.out.println("Client: Cannot bind Effectenbeurs");
System.out.println("Client: RemoteException: " + ex.getMessage());
Effectenbeurs = null;
} catch (NotBoundException ex) {
System.out.println("Client: Cannot bind Effectenbeurs");
System.out.println("Client: NotBoundException: " + ex.getMessage());
Effectenbeurs = null;
}
return Effectenbeurs;
}
public static void main(String[] args) {
if (locateRegistry) {
System.out.println("CLIENT USING LOCATE REGISTRY");
} else {
System.out.println("CLIENT USING NAMING");
}
// // Get ip address of server
Scanner input = new Scanner(System.in);
System.out.print("Client: Enter IP address of server: ");
String ipAddress = input.nextLine();
// Get port number
System.out.print("Client: Enter port number: ");
int portNumber = input.nextInt();
// Create client
BannerController client = new BannerController(ipAddress, portNumber);
}
@Override
public void start(Stage primaryStage) throws Exception {
}
}
I highly doubt the third class has anything to do with this problem, but just in case: I included it.
AEXBanner: package client;
import java.rmi.RemoteException;
import javafx.animation.AnimationTimer;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class AEXBanner extends Application {
public static final int WIDTH = 1000;
public static final int HEIGHT = 100;
public static final int NANO_TICKS = 20000000;
// FRAME_RATE = 1000000000/NANO_TICKS = 50;
private Text text;
private double textLength;
private double textPosition;
private BannerController controller;
private AnimationTimer animationTimer;
private Timeline timeline;
private int TIMERTICK = 200;
private int frame = 0;
private String koersen;
public void setController(BannerController banner) {
//controller = banner(this);
}
@Override
public void start(Stage primaryStage) {
Font font = new Font("Arial", HEIGHT);
text = new Text();
//controller = new BannerController(this);
text.setFont(font);
text.setFill(Color.BLACK);
Pane root = new Pane();
root.getChildren().add(text);
Scene scene = new Scene(root, WIDTH, HEIGHT);
primaryStage.setTitle("AEX banner");
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.toFront();
timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.setAutoReverse(false);
// Start animation: text moves from right to left
animationTimer = new AnimationTimer() {
private long prevUpdate;
@Override
public void handle(long now) {
long lag = now - prevUpdate;
if (lag >= NANO_TICKS) {
// calculate new location of text
// TODO
if (textPosition < 0 - textLength) {
textPosition = WIDTH;
}
textPosition -= 5;
text.relocate(textPosition, 0);
prevUpdate = now;
}
}
@Override
public void start() {
prevUpdate = System.nanoTime();
textPosition = WIDTH;
text.relocate(textPosition, 0);
//setKoersen("Nothing to display");
super.start();
}
};
animationTimer.start();
}
public void setKoersen(String koersen) {
text.setText(koersen);
textLength = text.getLayoutBounds().getWidth();
}
}
So to conclude with my question (just to make it clear): when the RMI server is running, I need to start this project with the StartClient. The StartClient launches the BannerController. I'd like to be able to start the program directly with the BannerController class.
Any tips or possible solutions would be greatly appreciated!
EDIT: After the changeg suggested by Lasagna, this error comes up directly when I start the BannerController:
Exception in Application constructor
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class client.BannerController
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodException: client.BannerController.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:818)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
... 1 more
Exception running application client.BannerController
D:\Dropbox\HBO ICT\Leerjaar 2\GSO3\AEXBanner Week 1\nbproject\build-impl.xml:1051: The following error occurred while executing this line:
D:\Dropbox\HBO ICT\Leerjaar 2\GSO3\AEXBanner Week 1\nbproject\build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 0 seconds)
Upvotes: 1
Views: 1385
Reputation: 1044
Lets take a look at your error.
sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767) Caused by: java.lang.IllegalStateException: Not on FX application thread; currentThread = main
This is saying that you have no "FX Application Thread" and your current Thread is "main."
This is because you are trying to work with the main method as your "main method" but in FX, it doesn't work like that (funky huh? :) ). main is just a method to launch the FX Application itself, which is why you get this error.
The start method of your Application is where things happen.
In your first class "StartClient" you use the main of "BannerController" and then in your main you "launch(args)
" which is how you launch your FX Application.
In your Banner Application, you have a main class with a bunch of stuff, but no launch(args)
I also am not sure why "start" is throwing an exception with no code inside of it.
So what you need to do is
"launch(args)"
within the main method.so take this code
public static void main(String[] args) {
if (locateRegistry) {
System.out.println("CLIENT USING LOCATE REGISTRY");
} else {
System.out.println("CLIENT USING NAMING");
}
// // Get ip address of server
Scanner input = new Scanner(System.in);
System.out.print("Client: Enter IP address of server: ");
String ipAddress = input.nextLine();
// Get port number
System.out.print("Client: Enter port number: ");
int portNumber = input.nextInt();
// Create client
BannerController client = new BannerController(ipAddress, portNumber);
}
@Override
public void start(Stage primaryStage) throws Exception {
}
and change it to
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
if (locateRegistry) {
System.out.println("CLIENT USING LOCATE REGISTRY");
} else {
System.out.println("CLIENT USING NAMING");
}
// // Get ip address of server
Scanner input = new Scanner(System.in);
System.out.print("Client: Enter IP address of server: ");
String ipAddress = input.nextLine();
// Get port number
System.out.print("Client: Enter port number: ");
int portNumber = input.nextInt();
// Create client
BannerController client = new BannerController(ipAddress, portNumber);
}
Upvotes: 1