I am currently working on a multi-threaded socket based Java program that should allow multiple threads to send request to this program. This should be handled with the event activation but I am having hard time understanding events and their implementation. Below is the code that should allow more than 1 thread to communicate with the program but I only have 1 thread there. Can someone please shed more light on this? Much appreciated.
//this is a a threads class
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Niti implements Runnable {
public String line;
public Socket soc;
public boolean active=true;
public Niti(Socket soc)
{
this.soc=soc;
this.line=line;
this.active=active;
}
public synchronized void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(soc.getInputStream()));
line=br.readLine();
while(line!=null && !line.equals("")){
if(!this.active)
break;
System.out.println(line);
line=br.readLine();
}
BufferedOutputStream bos = new BufferedOutputStream(soc.getOutputStream());
bos.write("Poruka iz Programa".getBytes());
}
catch (IOException ex) {
Logger.getLogger(Niti.class.getName()).log(Level.SEVERE, null, ex);
}
try {
soc.close();
} catch (IOException ex) {
Logger.getLogger(Niti.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
//and this is the main class
public class Server{
public static synchronized void main(String[] args) throws IOException, InterruptedException{
ServerSocket ss = new ServerSocket(1000);
while(true){
Socket sokit = ss.accept();
Niti n = new Niti(sokit);
while(true){
Thread t = new Thread(n);
t.start();
//Thread.sleep(4000);
//n.active=false;
System.out.println("nit broj:" + Thread.currentThread().getId());
}
}
}
}
Well, without look to Niti class (that is the client handler class as I suppose) you have a logic error here:
while(true){
Socket sokit = ss.accept();
Niti n = new Niti(sokit);
while(true){ // LOGIC ERROR!!!
Thread t = new Thread(n);
t.start();
//Thread.sleep(4000);
//n.active=false;
System.out.println("nit broj:" + Thread.currentThread().getId());
}
}
With the above code you are creating infinit Threads after pass the first time through accept method. What you have to do is to remove the second while(true), like this:
while(true){
Socket sokit = ss.accept();
Niti n = new Niti(sokit);
Thread t = new Thread(n);
t.start();
//Thread.sleep(4000);
//n.active=false;
System.out.println("nit broj:" + Thread.currentThread().getId());
}
Related
SSCCE:
package sample;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
ListView<Integer> root = new ListView<Integer>();
ObservableList<Integer> data = Model.getInstance().getData();
root.setItems(data);
// A Thread that simulates changes to GUI Observant List.
Thread populate = new Thread(()->{
for(int i=0;i<20000;i+=1){
int finalInstance = i;
// Changes are done on FXThread
Platform.runLater(()->{
data.add(finalInstance);
});
try{
Thread.sleep(5);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});populate.start();
// Populates at 200 elements/s
// Server Thread that Sends current status of ObservableList<Integer> data
Thread server = new Thread(()->{
try{
// Server Socket
ServerSocket ss = new ServerSocket(5555);System.out.println("SERVER ONLINE:");
while(true){
Socket s = ss.accept();
// Client Handler Thread to Handle Clients
Thread clientHandler = new Thread(()->{
try{
System.out.println("SERVER CLIENT:"+s);
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
List<Integer> dataCopy = new ArrayList<Integer>();
// Get Current Status of data List that is being used in FXThread adn store in dataCopy
Semaphore waitForReadToComplete = new Semaphore(0);
Platform.runLater(()->{
System.out.println("EXPECTED LENGTH: "+data.size());
for(Integer a:data){
dataCopy.add(a);
try{
Thread.sleep(5); // Simulate delay while copying large elements
}catch (InterruptedException e){e.printStackTrace();}
}
waitForReadToComplete.release(); // Marks Read Operation Complete
});
waitForReadToComplete.acquire();// Resumes Client Thread
oos.writeObject(dataCopy);oos.flush();
s.close();
}catch (InterruptedException | IOException e){
e.printStackTrace();
}
});clientHandler.start();
}
}catch(IOException e){
e.printStackTrace();
}
});server.start();
// Client Thread that requests for current status of ObservableList<Integer> data.
Thread client = new Thread(()->{
try{
Thread.sleep(1000);
Socket s = new Socket(InetAddress.getLocalHost(),5555);
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
List<Integer> dataCopy;
dataCopy = (ArrayList<Integer>)ois.readObject();
s.close();
System.out.println("ACTUAL LENGTH RECIEVED BY CLIENT "+dataCopy.size());
}catch (IOException | ClassNotFoundException | InterruptedException e){
e.printStackTrace();
}
});client.start();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
// Singleton Class with Eager Initialization
class Model{
static Model onlyInstance = new Model();
ObservableList<Integer> data = FXCollections.<Integer>observableArrayList();
public static Model getInstance(){
return onlyInstance;
}
public ObservableList<Integer> getData(){
return data;
}
}
In this example, I intend to send over the status of the data List to a client when it connects to my Server Thread.
The problem is that every time I want to read the data List, I need to do it using a Platform.runLater() call, whose scheduling is not in my control.
I use a Semaphore to block the Server's Client Handler thread in order to make sure that the complete List is copied and then sent to the client.
As visible, This method makes my client wait for a longer period of time since copying the data List is done inside Platform.runLater().
I was wondering if there was a better way to share my data List between the FXThread and Background Threads.
EDIT:
Better wording, courtesy of #James_D
I have a model with some (possibly large amount of) data. The model is being updated by a background thread. The server has access to the model and sends the data on demand to network-connected clients. And then there's a UI, which is server-side. And I want the UI to display the current state of the model on the server-side and perform add/remove operations on the data from the UI user.
I suggest using a Model shared between the javafx Application, the modifying thread, and the server:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
public class Main extends Application {
private Model model;
#Override
public void start(Stage primaryStage) throws Exception{
ListView<Integer> listView = new ListView<>();
ObservableList<Integer> data = listView.getItems();
model = new Model();
model.getData().addListener(
(ListChangeListener<Integer>) listener -> {
listener.next();
Platform.runLater(()-> data.addAll(listener.getAddedSubList()));
}
);
populate();
new Server(model, 5555).activate();
new Client("localhost",5555).activate();
primaryStage.setScene(new Scene(listView, 300, 275));
primaryStage.show();
}
private void populate() {
Thread populate = new Thread(()->{
for(int i=0;i<20000;i+=1){
model.addData(i);
try{
Thread.sleep(50);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});populate.start();
}
public static void main(String[] args) {
launch(args);
}
}
class Model{
private final ObservableList<Integer> data = FXCollections.<Integer>observableArrayList();
private final ObservableList<Integer> readOnlyData = FXCollections.unmodifiableObservableList(data);
synchronized void addData(int i){
data.add(i);
}
public ObservableList<Integer> getData(){
return readOnlyData;
}
}
The Server definition, including ServerThread to support multiple clients:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javafx.collections.ObservableList;
public class Server {
private final ExecutorService pool;
private final List<ServerThread> clients;
private final int portNumber;
private boolean stop;
private ServerSocket serverSocket;
private final Model model;
Server(Model model, int portNumber) {
this.model = model;
this.portNumber = portNumber;
pool = Executors.newFixedThreadPool(3);
clients = new ArrayList<>();
}
private void runServer(){
System.out.println("SERVER: Waiting for client");
try{
serverSocket = new ServerSocket(portNumber);
stop = false;
while(! stop){//do in loop to support multiple clients
Socket clientSocket = serverSocket.accept();
System.out.println("SERVER: client connected");
ServerThread st1 = new ServerThread(model.getData(), clientSocket);
pool.execute(st1);
clients.add(st1);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
closeSocket();
}
}
public void stop(){
for( ServerThread st : clients) {
st.stopServerTread();
}
stop = true;
pool.shutdown();
closeSocket();
}
public void activate(){
new Thread(()->runServer()).start();
}
private void closeSocket() {
try {
serverSocket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
class ServerThread extends Thread {
private Socket socket = null;
private boolean stop;
private final ObservableList observableList;
public ServerThread(ObservableList<Integer> observableList ,Socket socket) {
this.observableList = observableList;
this.socket = socket;
}
#Override
public void run() {
try{
stop = false;
DataInputStream in = new DataInputStream( socket.getInputStream() );
DataOutputStream out = new DataOutputStream( socket.getOutputStream() );
String fromClient;
while(! stop){
if((fromClient = in.readUTF()) != null) {
System.out.println("SERVER: recieved message - " + fromClient);
out.writeUTF("Data size is " + observableList.size());
}
}
} catch (IOException e) {
e.printStackTrace();;
}
}
void stopServerTread(){
stop = true;
}
}
And finally the client which requests info from the server:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;
public class Client{
private final int portNumber;
private final String hostName;
private boolean stop;
Client(String hostName, int portNumber ) {
this.hostName = hostName;
this.portNumber = portNumber;
}
private void runClient(){
try {
stop = false;
Socket socket = new Socket(hostName, portNumber);
DataInputStream in = new DataInputStream( socket.getInputStream() );
DataOutputStream out = new DataOutputStream( socket.getOutputStream() );
while (! stop) {
out.writeUTF("Request Size"); //any not null string to get server response
String fromServer = in.readUTF();
System.out.println(fromServer);
TimeUnit.SECONDS.sleep(1);
}
} catch (UnknownHostException e) {
e.printStackTrace();
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}catch (InterruptedException e){
e.printStackTrace();
}
}
public void activate(){
new Thread(()->runClient()).start();
}
public void stop(){
stop = true;
}
}
One thing that you could change is the order that your submitting your tasks. Instead of starting the client thread, then calling run later and waiting for the response. Just call Platform.runLater, populate the copy and then start the client thread. Now there is no reason for a semaphore.
// Immediately following the accept.
Platform.runLater(()->{
System.out.println("EXPECTED LENGTH: "+data.size());
List<Integer> dataCopy = new ArrayList<>(data);
Thread clientHandler = new Thread(()->{
try(ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()) ) {
System.out.println("SERVER CLIENT:"+s);
oos.writeObject(dataCopy);
oos.flush();
}catch (InterruptedException | IOException e){
e.printStackTrace();
}
});
clientHandler.start();
});
Creating a new thread each time should be replaced with an executor service of some sort. Depending on the task, consider using javafx.concurrent Task. Your server loop could be a task for example.
It's possible to expose an view of the data backing your observable list.
List<String> cowal = new CopyOnWriteArrayList<>();
ObservableList<String> data = FXCollections.observableList(cowal);
List<String> dataCopy = Collections.unmodifiableList(cowal);
I made it a copy on write array list so you can iterate over the view without getting a CCME. I called it a dataCopy to be consistent with the previous naming, but it is a view of the data.
Also, as a matter of taste, instead of });server.start(); create a new line to call server.start();
I've a client class which tries to connect to a server. But as you know you can't
execute network operations on the Main UI thread. So I've to create different threads for each operation.
Current code:
package com.example.justus.rocchat;
import android.os.AsyncTask;
import android.util.JsonWriter;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
/**
* Created by justus on 13-1-2015.
*/
public class Client
{
private String name;
private int port;
private String hostAddress;
private Socket socketClient;
private MainActivity mainActivity;
public boolean isConnected;
public Client(MainActivity mainActivity, String hostAdress, int port)
{
this.hostAddress = hostAdress;
this.port = port;
this.mainActivity = mainActivity;
}
public void send(final byte[] data)
{
Thread sendThread = new Thread(new Runnable() {
public void run()
{
try
{
DataOutputStream out = new DataOutputStream(socketClient.getOutputStream());
out.write(data);
System.out.println("writed data");
} catch (IOException ex) {
}
}
});
sendThread.start();
}
public void connect()
{
Thread connectThread = new Thread(new Runnable() {
public void run() {
try
{
System.out.println("trying to connect");
socketClient = new Socket(hostAddress, port);
isConnected = true;
}
catch(UnknownHostException ex)
{
System.out.println("ex:" + ex.getMessage());
}
catch (IOException ex)
{
System.out.println("ex:" + ex.getMessage());
}
}
});
connectThread.start();
}
}
Isn't this a little to much? Are there any better ways to handle this operations?
Already thanks for your time.
AsyncTask is the accepted way of handling asynchronous operations. It is a wrapper around the Thread class and is part of the Android SDK. They should only be used for operations that last under a few seconds, for longer operations you should use a Service.
developer.android.com/reference/android/os/AsyncTask.html
There are 2 options that you have
Use AsyncTask - much easier, object oriented that using threads but only for shortlived tasks (under 30 secs)
Use RoboSpice - https://github.com/stephanenicolas/robospice
Of the two, I prefer RoboSpice
I am trying to implement a simple program which allows to join a Multicast group on a virtual IP address and listen packets that are sent to this IP (that is why I created the class ThreadGroup).
My code is :
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class MulticastTest {
private Set<Thread> threads;
public MulticastTest(){
threads = new HashSet<Thread>();
}
/**
* #param args
*/
public static void main(String[] args) {
MulticastTest test = new MulticastTest();
test.joinGroup("dogg",test.createAdr(),32445);
}
private void joinGroup(String name, String adr, int port){
try {
MulticastSocket multi = new MulticastSocket(port);
multi.joinGroup(InetAddress.getByName(adr));
ThreadGroup newThread = new ThreadGroup(multi);
threads.add(newThread);
newThread.start();
System.out.println("Congrats you joined the group "+name+".");
}catch (NumberFormatException | IOException e) {
e.printStackTrace();
}
}
private String createAdr(){
Random r = new Random();
return r.nextInt(16)+224 + "." + r.nextInt(256) + "." + (r.nextInt(255)+1) + "." + r.nextInt(56);
}
/**
* Thread to receive datagram that are sent to the group
*/
class ThreadGroup extends Thread {
MulticastSocket multiSocket;
public ThreadGroup(MulticastSocket m) throws IOException{
multiSocket = m;
start();
}
public void run() {
DatagramPacket message;
byte[] contMessage;
String texte;
while(true) {
contMessage = new byte[1024];
message = new DatagramPacket(contMessage, contMessage.length);
try {
multiSocket.receive(message);
texte = (new DataInputStream(new ByteArrayInputStream(contMessage))).readUTF();
System.out.println(texte);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
So in my main, I try to connect to a random Multicast InetAddress and wait packets. But when I run my program, I get :
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:705)
at MulticastTest.joinGroup(MulticastTest.java:35)
at MulticastTest.main(MulticastTest.java:25)
Could somebody explain to me what I am doing wrong ?
You are calling start() on your thread twice, once in the constructor and once in joinGroup(). Remove start() from the constructor that should get you past the IllegalThreadSTateException.
you have start thread two times.
1) ThreadGroup constructor
2) newThread.start();
use either of one ,your problem may be solved.
my client/server works perfectly for one message, then no matter what's next it says it's blank.
I believe the problem resolves in here or my commands class:
package MyServer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
public class Main {
public static String line;
public static void main(String[] args){
while(true){
try {
//Creates a socket to receive commands from!
Socket socket = new Socket("localhost", 7586);
//Uses that socket to create a Reader to read the commands!
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//Waits for Lines to be sent and then executes them!
while(true){
line = in.readLine();
if(line != null){
Commands.ReceiveCommand();
}else {
break;
}
}
} catch (UnknownHostException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
or in my commands:
package MyServer;
import javax.swing.JOptionPane;
public class Commands {
static String command = (Main.line).toString(); //<--This was the problem, just had to move it into the method below.
public static void ReceiveCommand(){
if(command.equals("test")){
JOptionPane.showMessageDialog(null,"works","command: " + command,JOptionPane.WARNING_MESSAGE);
//System.out.println("WORKEDS MOFO");
command = "";
}else{
JOptionPane.showMessageDialog(null,"not recognized","command: " + command,JOptionPane.WARNING_MESSAGE);
//System.out.println("no bueno");
//System.out.println("line is " + command);
command = "";
}
}
}
Edit: For some reason when debugging, command is just blank no matter what after it's been used once, so it might be in my main server class:
package MyClient;
import java.util.List;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Main {
//Sets the Port
final static int PORT = 7591;
//Creates a list of Connected Clients
static List<Socket> connectedClients = new ArrayList<Socket>();
public static void main(String[] args){
//Creates a Thread to Send Messages to connectedClients
new Thread(new messageThread()).start();
try {
//Creates the ServerSocket
ServerSocket serverSocket = new ServerSocket(PORT);
while(true){
//Waits for a Connection and Accepts it...
Socket clientSocket = serverSocket.accept();
System.out.println("A Client has connected!");
//Adds it to the List
connectedClients.add(clientSocket);
}
} catch (IOException e) {
e.printStackTrace();
}
} }
and the messageThread:
package MyClient;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class messageThread implements Runnable {
public void run() {
while(true){
System.out.println(">>");
Scanner in = new Scanner(System.in);
String command = in.nextLine();
for(Socket clientToSendCommand : Main.connectedClients){
try {
PrintWriter commandWriter = new PrintWriter(clientToSendCommand.getOutputStream());
commandWriter.println(command);
commandWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
This dosen't work, because th line
static String command = (Main.line).toString();
in the Commands-class is executed exactly once, when the Commands-class is first referenced.
When the second command is send, the class was already referenced, so this line is not executed again.
To solve this put the line inside the method, or - much better - pass it as a parameter to the method.
P.S.: Have you mixed up the packages? The class with the ServerSocket should be the server and thus be in the MyServer package. :-)
I would really appreciate help with my program. It is some sort of chat server with multiple clients.
Here's the server code:
package com.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static int PORT;
private ServerSocket server;
private Socket socket;
public Server(int port) throws IOException {
PORT = port;
server = new ServerSocket(PORT);
System.out.println("server started");
try {
while (true) {
socket = server.accept();
try {
new ServeClient(socket);
} catch (IOException e) {
socket.close();
}
}
} finally {
server.close();
}
}
public static void main(String[] args) throws IOException {
int port = Integer.parseInt(args[0]);
Server server = new Server(port);
}
}
I start the server and then create a Client. The server receives connection socket from socket
and creates a ServeClient Thread.
Here's ServeClient code:
package com.server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;
import com.gui.WindowManager;
public class ServeClient extends Thread {
private final Socket socket;
private BufferedReader in;
private PrintWriter out;
private String msg;
public static final String ENDSTRING = "END";
public static Vector clients = new Vector();
public ServeClient(final Socket socket) throws IOException {
this.socket = socket;
System.out.println("socket " + socket);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
start();
}
public void run() {
try {
clients.add(this);
while (true) {
msg = in.readLine();
if (msg == ENDSTRING)
break;
broadcast(msg);
}
System.out.println("closing...");
} catch (IOException e) {
System.err.println("IO EXCEPTION");
} finally {
try {
socket.close();
} catch (IOException e) {
System.err.println("SOCKET NOT CLOSED");
}
}
}
#SuppressWarnings("deprecation")
public void broadcast(String msg) {
synchronized (clients) {
Enumeration<ServeClient> e = clients.elements();
while (e.hasMoreElements()) {
ServeClient serveClient = e.nextElement();
try {
synchronized (serveClient.out) {
serveClient.out.println(msg);
}
} catch (Exception eee) {
serveClient.stop();
}
}
}
}
}
What i get is a NullPointerException when ServeClient invokes run() method
server started
socket Socket[addr=/127.0.0.1,port=51438,localport=8888]
Exception in thread "Thread-0" java.lang.NullPointerException
at com.server.ServeClient.run(ServeClient.java:33)
line 33 is the line with first "try" statement in ServeClient run() method
com.server.ServeClient.run(ServeClient.java:33)
I don't believe that it's happening at the try.
Open up an IDE, turn on debugging, and step through until you can see what's happening. That's the fastest way to figure out what you've missed.
There's an object that you're assuming is fine that is not. Find it.
Here's an example of how to do this properly:
http://www.kodejava.org/examples/216.html
Your problem is with the order in which static instance variables are initialised. Try doing something like:
...
private static Vector clients = null;
...
if (clients==null) {
clients = new Vector(); // consider putting this in a synchronized block
}
before you add the client to the vector.
Sorry for necroing such an old issue but it seemed like this problem wasn't resolved, so I'll give a bit of input from my end.
I've had a similar problem and the compiler also kept telling me that the problem was at the start() method. However, when I commented out the thread part and just ran the code on the same thread as the UI, the compiler directed me to the real source of the problem: the code inside the thread.
After making sure the code didn't give an error, I enclosed the code with the original thread code, and it stopped giving me the NullPointerException error.
Hope this helps someone along the way.
Remove the duplicate class declaration in JPanel.
I was trying to run a timer thread that updated a clock in the main application window.
I had created the JFrame with Eclipse/WindowBuilder and had followed a tutorial on how to make a timer. I had copied the declaration of the textfield into the class declaration to make it available for the entire class, but forgot to remove the Class Id in front of the widget definition. So it still initialized the local instance and not the global one. Thus when I accessed the global one it was still null.