I'm currently learning Java by developing a tool for creating and filling out multiple-choice-forms client-side and saving aswell as evaluating them server-side. I used a code skeleton from a RMI Tutorial for the network-part and it was working fine until just now. Both the client and the server application are in the same package but run as seperate applications. For easier developing they're both running on the same system right now, although this will change when things are done.
So let's cut to the chase with some code and what exactly goes wrong:
Server.java
Server() throws RemoteException {
super();
}
public static void main(String[] args) {
try {
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
}
catch (RemoteException ex) {
System.out.println("SERVER: " + ex.getMessage());
}
try {
Naming.rebind("Server", new Server()); <---
}
catch(MalformedURLException ex) {
System.out.println("SERVER: " + ex.getMessage());
}
catch(RemoteException ex) {
System.out.println("SERVER: " + ex.getMessage());
}
}
[...] methods that are called by the client via ServerInterface
The <--- marks where the Client-GUI is started.
Client.java
private static Gui_loadSets gui_loadSets = new Gui_loadSets();
public static void main(String[] args) {
loadGuiLoadSets();
}
This is where the first GUI is turned visible; the one to choose a form to load from. This GUI is loaded by starting the server EVEN IF I COMMENT THIS OUT. So the Server doesn't really load the Client-App, but instead somehow magically accesses it's GUI and showing it for no reason.
I already tried "stepping into" the line before the GUI is loaded, but I end up in an infinite loop eventually, so I really have no idea what is going an.
This is my first question here, so please forgive me if I missed out anything obvious.
Thanks for your help in advance. If you need any more code I'd be happy to supply, but most of the remaining code is all about the multiple-choice-forms.
Naming.rebind() needs a URL, not just a service name. It should be
Naming.rebind("rmi://localhost/Server", new Server());
But I'm puzzled by your comment on this line. The --> doesn't 'mark where the Client-GUI is started', it marks the line where the remote object is constructed, exported, and bound into the Registry. The client GUI is at the client.
Thanks for your effort, I got it working now.
A very basic class the server was creating an object from was referring to a method provided by the client. So apparently this caused the problem. I must've forgotten about it, since it was in there since the beginning but somehow just now started to turn out to be a visible problem.
I'm sorry for any inconvenience my bad design has caused you. :)
Also, how do I mark this problem as solved without being frowned upon? Do people attach importance to getting the accepted-answer-button? I can't do this on comments I believe.
Related
It's been days that I struggle to make a basic Client / server communication using websockets
My client is a java client with libGDX and my server is a basic java server
My main goal is to compile my client into HTML5 to communicate with my server using websockets.
I tryed the following solution when searching on google :
https://github.com/czyzby/gdx-lml/tree/master/websocket
https://github.com/pepedeab/libGDX-Net
https://github.com/TooTallNate/Java-WebSocket
The 1 seemed to be the best solution but, it doesn't seems to have the TCP_NODELAY socket setting (which is essential in my case)
The 2 seemed an other good solution too, But it relies on http://code.google.com/p/gwt-ws/(which at this time don't understand the point of this)
The 3 is what I choosed, a simple WebSocket Java API to let me write client and server really easily.
It worked very well for desktop and android, but when I tryed to html:dist, gradle give me error about websocket which was not inherit etc...
My main build.gradle file contains this line for each project (core, desktop, android, html) : compile "org.java-websocket:Java-WebSocket:1.3.7"
So to resume my primary question : How to correctly establish a websocket connection with a client compiled with GWT in ligdx, with in addition TCP_NODELAY?
My client is a very simple class :
package com.mygdx.game;
import java.net.URI;
import java.nio.ByteBuffer;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.handshake.ServerHandshake;
public class WebSocketsNet extends WebSocketClient {
public WebSocketsNet(URI serverUri, Draft draft) {
super(serverUri, draft);
}
public WebSocketsNet(URI serverURI) {
super(serverURI);
}
#Override
public void onOpen(ServerHandshake handshakedata) {
send("Hello, it is me. Mario :)");
System.out.println("new connection opened");
}
#Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("closed with exit code " + code + " additional info: " + reason);
}
#Override
public void onMessage(String message) {
System.out.println("received message: " + message);
}
#Override
public void onMessage(ByteBuffer message) {
System.out.println("received ByteBuffer");
}
#Override
public void onError(Exception ex) {
System.err.println("an error occurred:" + ex);
}}
According to https://bugs.webkit.org/show_bug.cgi?id=102079 and https://groups.google.com/forum/#!topic/native-client-discuss/T8zdrMjiTAE, found via https://github.com/websockets/ws/issues/791 and https://github.com/varspool/Wrench/pull/104, most browsers already use TCP_NODELAY. At least from the websocket standard, there is nothing you can do to influence this on the client - on the server there may be more options.
If TCP_NODELAY is already set on the client, you can set it on the server as well to ensure both sides are sending small messages as soon as possible.
Another thought that is suggested in questions like https://stackoverflow.com/a/13406438/860630 is to respond to every message sent right away, so that the network stack flushes all remaining messages as soon as possible.
Finaly I found a way to make it work, so I post a answer here for those interested.
I used https://github.com/czyzby/gdx-lml/tree/master/websocket
Particulary the example package, and rigorously follow everything that need to be added on build.gradle and on differents xml files, so now it work !
So to conclude :
Server Listening websockets with java-web-socket
LIBGDX client use gdx-websockets to connect to the server (Watch-out for different build gradle file and xml !!)
Hope to help some people who were in the same problem like me !
I am currently writing a small Java applet to access HBase data using the REST API. Accessing the data using Java is not particularly difficult, I have done this successfully. When running on a machine in my HDP cluster, the results are perfect. However when running as an applet I get no results at all. (I have chosen an applet since distributing an executable JAR is something my boss wants to avoid)
Having finally found what I believe to be the underlying issue, I have found the following runtime exception: hbase-default.xml file seems to be for an older version of HBase (null), this version is 1.1.2.2.4.0.0-169. My assumption is that this is caused by the fact that my local machine does not have HBase at all. The intention is that users will be able to view their own data from a local machine, and so I cannot expect all users to have HBase (or anything other than a browser)
My question really has two parts:
Is there anyway to get an applet like this to work?
Is there a better alternative to an applet for this kind of work?
Posting my code in case I have made some significant mistake:
public class HBaseConnector extends JApplet
{
private Cluster cluster;
public void init()
{
System.out.println("Applet initialising");
cluster = new Cluster();
cluster.add("hbase_server", 9080);
}
public void start()
{
System.out.println("Applet starting");
Client client = new Client(cluster);
RemoteHTable table = new RemoteHTable(client, "table_name");
Get get = new Get(Bytes.toBytes("key"));
get.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("Record"));
try
{
Result result1 = table.get(get);
JOptionPane.showMessageDialog(null, Bytes.toString(result1.getValue(Bytes.toBytes("f1"), Bytes.toBytes("Record"))), "Result", JOptionPane.INFORMATION_MESSAGE);
}
catch (Exception ex)
{
System.err.println("Exception occurred");
}
}
public void stop()
{
System.out.println("Applet stopping");
}
public void destroy()
{
System.out.println("Applet destroyed");
}
}
While I haven't been able to solve this problem for an applet itself, I managed to get the app working by moving over the a JNLP app (JNLP). Given this, I suspect the underlying problem was a permissions issue due to the fact that applets run in a sandbox. This is fine, since I am aware that most browsers are moving away from Java plugins.
Another possible cause I discovered: hbase-default.xml must be in the root folder of the jar.
I am working in a client-server application(web start) which is started by url http:\[ip of server]:[port]. It loads index.html in the browser and main application pops up in another window and here we have several option to see/perform status/action.
Recently i got an issue of server status being displayed as unknown which is default, but it after loading application it should be loaded. I found the cause of it, that method to display server status being executed at start, so i use while loop to check if application loads, then i executed that method. It worked.
But if i exit the pop up(main application) and refresh the url in main browser window, application pops up successfully but without server status, There is nothing about server status. It leads me to think that while cut the pop up, serverStatus class did not unload.
I tried to learn about class loader but did not get anything and not able to find anything in application source code about loading/unloading of a class.
Could someone please guide or give reference to a study materiel that could solve my problem.
Please pardon me if i am not clear in asking the exact question and please ask if more information is required. Thanks in Advance
The changed code is here:
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
PrintWriter out = new PrintWriter(
new OutputStreamWriter(response.getOutputStream(), "UTF-8"));
synchronized(this){
while(!notCompleted){
Thraed.sleep(100)}
out.println("<LABEL><B>" + discoveryStatusLabel_ +
" :</B></LABEL> <SPAN ID='DiscoveryStatus'>" +
discoveryStatus_ + "</SPAN>");}
}
where i added the while loop, and notCompleted is variable to check if application loaded fully.
Note: There are more code in doGet() and synchronized block apart from this.
I'm developing a chat server based on XMPP and Smack API, which connects to an Openfire server (Hosted by a friend who is also developing this with me).
So, I started programming it just a few days ago (Netbeans on OS X 10.8), and today I went on to the connection and login aspects.
I can login perfectly with the right choice of username+password :P but I don't know how to handle an invalid login attempt and let the app show a message and then allowing the user to retry.
Here's my code, which fires after user has pressed a button in my Swing JForm:
(Note: XMPPConnection object is already created in another class, and the connection has been made to the server. You can see I'm calling the object from that another class)
private void btnIniciarSesionActionPerformed(java.awt.event.ActionEvent evt) {
String Usuario = txtUsuario.getText();
String Password = new String (pwdContrasena.getPassword());
if (Usuario.equals("") || Password.equals("")){
// Missing data
JOptionPane.showMessageDialog(null, "Missing data");
}
else{
//Try to login
try{
Proyecto_chat.conexion.login(Usuario, Password, "x");
}
catch (XMPPException ex){
Logger.getLogger(Ventana_login.class.getName()).log(Level.SEVERE, null, ex);
// Problem
}
if (Proyecto_chat.conexion.isAuthenticated() == true){ //Login has been successful
jLabel1.setVisible(false);
System.out.println("Authenticated as " + Usuario);
JOptionPane.showMessageDialog(null, "Authenticated as " + Usuario);
//Exit login window and carry on
}
else{
JOptionPane.showMessageDialog(null, "login error");
}
}
}
Should I play with that exception I'm getting? ->
SEVERE: null
SASL authentication DIGEST-MD5 failed: not-authorized:
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:337)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:203)
at proyecto_chat.Ventana_login.btnIniciarSesionActionPerformed(Ventana_login.java:159)
at proyecto_chat.Ventana_login.access$100(Ventana_login.java:15)
at proyecto_chat.Ventana_login$2.actionPerformed(Ventana_login.java:73)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
(...) more lines that I think are not critical for this
As passwords are stored in plain text (University project, so it doesn't matter) for simplifying changing them from inside the application, I can connect to the database (PostgreSQL in remote server) from the client computer, and check the passwords and only do 'conexion.login' if user&pass matches, but that would be... you know... wrong
After looking around on the web with no luck, I decided to head over here, ask, go to sleep and wake up next morning with some suggestions ;)
Help shall be appreciated
Not sure if I understand what you are asking but if it's "How can I determine the reason for a failed login attempt with Smack?" then here is my answer:
You have to evaluate the (XMPP)Exception's message string as of Smack 3.2.2 if you want to determine the reason for the failed login. These message strings that distinguish between the various failure reasons are currently hard-coded in the source, which is usually not a good idea.
A while ago I have created SMACK-416 "Improve Exceptions on connect() and login()" to address this issue. The idea is to replace the hard-coded strings/failure reasons with a class hierarchy. But it sure will take a few months until this is implemented (and maybe a few weeks/months/years until it is released).
Actually, the main problem was that when I tried to login using an invalid username/password, some exception was thrown (As well as an information display that I set up), but the application wouldn't let me log in again (As if I corrected my data and clicked the button again).
I finally solved this by placing the .connect() right behind the .login() method, and calling .disconnect() in case a bad login was made, so the server would be reconnected every time the user tried to log in .
This might not be the ideal approach, but I find it easy and do-able. Thanks for helping!
Please excuse my noobishness as I am teaching myself Java and don't know a lot.
I'm trying to make a multiplayer game that runs from Java applets, I have a server-side program working that will accept strings of text, but all my attempts to find code for applets have failed.
My best attempt looks like it works but I think fails to connect to the server, any ideas why? (localIP is my correct IP and works fine in other tests)
public void init()
{
try
{
socket = new Socket(localIP, 5555);
inStream = new DataInputStream(socket.getInputStream());
outStream = new PrintStream(socket.getOutputStream());
}
catch(Exception e)
{
never reached
}
}
I don't mind scrapping this if someone can tell me a better way to do it or any way at all.
a java applet can only connect to the server from which it was downloaded. if you are not loading the applet from localIP, then you will not be able to connect to it.
you may be able to get around this restriction by signing the applet.
Given that you are not using the Http Protocol, One assumes that the applet is loaded from another port other than 5555. If this is the case, the applet needs to be signed in order to do this functionality.