New to Java and don't understand the underlying mechanisms of the following...
Hi,
I've been programming in .NET for a few years and recently started learning Java. As an exercise I want to remake a server-client application I made in C# a while ago, but I encounter problems that I don't understand. First some code:
Code:
package sandsserver;
import java.net.*;
public class ConnectionsHandler
{
void startListening()
{
ServerSocketThread serverSocketThread = new ServerSocketThread(serverSocket);
serverSocketThread.start();
}
void stopListening()
{
try
{
serverSocket.close();
}
catch(Exception ex)
{
System.out.println("ex: kan serverSocket niet sluiten");
}
}
private ServerSocket serverSocket;
}
//-------------------------------------------------------------
package sandsserver;
import java.net.*;
public class ServerSocketThread extends Thread
{
private static final int PORT = 13713;
ServerSocketThread(ServerSocket socket)
{
serverSocket = socket;
}
@Override public void run()
{
if(serverSocket != null)
{
serverSocket = null;
}
try
{
serverSocket = new ServerSocket(PORT);
}
catch(Exception ex)
{
System.out.println("ex: kan serverSocket niet creeeren");
}
try
{
while(true)
{
System.out.println("in lus");
Socket incomingClient = serverSocket.accept();
}
}
catch(Exception ex)
{
System.out.println("ex: probleem in de lus");
}
System.out.println("uit lus");
}
private ServerSocket serverSocket;
}
When I call startListening, it works... the thread starts, but when stopListening is called, the program goes in the catch.
I tried some things and when I do the following it works:
Code:
ConnectionsHandler.java
...
void startListening()
{
serverSocketThread = new ServerSocketThread();
...
}
void stopListening()
{
try
{
serverSocketThread.getServerSocket().close();
}
...
}
private ServerSocketThread serverSocketThread; // I have a reference to the thread, where I had a reference to the socket
ServerSocketThread.java
...
//ServerSocketThread(ServerSocket socket)
//{
//serverSocket = socket;
//}
// No constructor anymore, since the socket gets created in this class
ServerSocket getServerSocket()
{
return serverSocket;
}
// I added this function to get access to the socket
So... can anyone explain me why this works now? I do the same thing (I think). The first one would be my favorite one because I don't want to keep a reference to the thread, I just need the reference to the socket.
Thank you in advance for an answer,
P.
Re: New to Java and don't understand the underlying mechanisms of the following...
It probably would have helped you if you had done:
Code:
void stopListening()
{
try
{
serverSocket.close();
}
catch(Exception ex)
{
// System.out.println("ex: kan serverSocket niet sluiten");
ex.printStackTrace();
}
}
That would have told you exactly what exception had been thrown, thus possibly answering your question as to why it threw an exception.
Re: New to Java and don't understand the underlying mechanisms of the following...
The stacktrace let me know the serversocket has a nullreference. Very strange, because the socket does exist. I guess I can't close the socket from another thread than the one I created it. If anyone knows more about this, or had tips for me about this topic, please shoot. :-)
Re: New to Java and don't understand the underlying mechanisms of the following...
No it doesn't exist.
You pass a null socket into the ServerSocketThread class.
The serverSocket attribute of ConnectionsHandler is never anything other than null.
Code:
ServerSocketThread(ServerSocket socket)
{
serverSocket = socket;
}
This means that the above constructor simply sets the serverSocket attribute in the ServerSocketThread object to null.
That attribute is later instantiated, but the one in ConnectionsHandler never is.
Indeed, even if that one was instantiated and then passed into the ServerSocketThread constructor, you would then (on run()) simply nullify it and create a new one:
Code:
if(serverSocket != null)
{
serverSocket = null;
}
...
serverSocket = new ServerSocket(PORT);
Re: New to Java and don't understand the underlying mechanisms of the following...
I thought that both serverSocket-variables referred to the same object; if I instantiate serverSocket in ServerSocketThread, the variable serverSocket in ConnectionsHandler wouldn't be null anymore... Gonna experiment a bit with this tomorrow.
Re: New to Java and don't understand the underlying mechanisms of the following...
Nope.
Java is pass by value.
Code:
void method1() {
SomeObject so = new SomeObject();
method2(so);
System.out.println(so);
}
void method2(SomeObject so) {
so = new SomeObject();
}
The reference (and that is all variables are, a reference to an object in memory) passed to method2 is a value, not a pointer to a reference, so the instantiation inside method2 has no effect whatsoever on the value of "so" in method1.
The same applies to your serverSocket variables (references).
Re: New to Java and don't understand the underlying mechanisms of the following...
I was so used for object to be passed by reference in C#, that I didn't think it would be different in Java. Thank you for making this clear!
Re: New to Java and don't understand the underlying mechanisms of the following...
Would that work in C#?
I know you can pass by ref, but will that continue to a later assignment which occurs as part of a completely different method call?
Re: New to Java and don't understand the underlying mechanisms of the following...
As far as I know, yes it would.
Re: New to Java and don't understand the underlying mechanisms of the following...
(C# syntax is not guaranteed to be correct)
Code:
void initialMethod(ref SomeOjbect par) {
someLocalPar = par;
}
void someLaterMethod() {
someLocalPar = new SomeObject();
}
If I call initialMethod() with a parameter, then at some later point call someLaterMethod(), then I really wouldn't expect C# to remember that at some point in the past someLocalPar was assigned from a ref parameter and thus be able to change that parameters reference to something else.
I think Jos knows C# so he might be able to shed light on it, assuming he ever looks in here.
Not that that's important to your problem of course.
Re: New to Java and don't understand the underlying mechanisms of the following...
I think someLocalPar keeps a reference to par until someLaterMethod() is raised.
Re: New to Java and don't understand the underlying mechanisms of the following...
I really can't see how it does that (or why it would bother).
Smacks of "magic"...and magic in code is a Bad Thing.
Re: New to Java and don't understand the underlying mechanisms of the following...
Not sure if it is the following that you are talking about, but I quickly made this example in C# to test it, the comments is what is shown in the console. :
C# code:
Code:
class Program
{
private theObject someLocalPar;
static void Main()
{
new Program();
}
Program()
{
theObject originalPar = new theObject("original");
Console.WriteLine(showPar(someLocalPar)); // null
Console.WriteLine(showPar(originalPar)); // original
initalMethod(originalPar);
Console.WriteLine(showPar(someLocalPar)); // original
Console.WriteLine(showPar(originalPar)); // original
someLaterMethod();
Console.WriteLine(showPar(someLocalPar)); // later
Console.WriteLine(showPar(originalPar)); // original
}
void initalMethod(theObject par)
{
someLocalPar = par;
}
void someLaterMethod()
{
someLocalPar = new theObject("later");
}
string showPar(theObject par)
{
if (par != null)
{
return par.aProperty;
}
else
{
return "null";
}
}
class theObject
{
public string aProperty { get; set; }
public theObject(string ap)
{
aProperty = ap;
}
}
}
So, someLocalPar doesn't forget its reference between different methods (you don't even need to add the ref keyword).
Re: New to Java and don't understand the underlying mechanisms of the following...
But that's not what you were doing in the Java.
You were expecting originalPar to change...which your code shows i doesn't.
Re: New to Java and don't understand the underlying mechanisms of the following...
Yeah, you're right. While we are discussing this. I have refactored my code and everything works good now. It seems that Java is less forgiving when you don't follow OO principles, where in C# you are forgiven.