Hot questions for Using Applets in server

Question:

I've tried to create a simple Client and Server applets in java card 2.2.2 using Eclipse 3.7 SDK using the Shareable Interfaces. When the method JCSystem.getAppletShareableInterfaceObject is called it throws an exception and so the return SW sets to 6F00.

This is the Client app code (Test_Client.java):

    package client;

import server.Test_ServerInf;
import javacard.framework.AID;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;

public class Test_Client extends Applet {

    protected static final byte INS1 = (byte)0xE2;
    protected static final byte INS2 = (byte)0x21;

    byte[] ServerAIDbyte={(byte)0x20,(byte)0x21,(byte)0x22,(byte)0x23,(byte)0x24,(byte)0x25,(byte)0x26,(byte)0x27,(byte)0x01};
    AID ServerAID;

    private Test_Client() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new Test_Client().register();
    }

    public void process(APDU apdu) throws ISOException {
        // TODO Auto-generated method stub
        byte[] apduBuffer = apdu.getBuffer();

        byte Ins=apduBuffer[ISO7816.OFFSET_INS];
        short byteread = apdu.setIncomingAndReceive();

        if (selectingApplet())
            return;

        switch (Ins){
        case INS1:
            Ins1_Handler(apdu);
            return;
        case INS2:
            Ins2_Handler(apdu,apduBuffer);
            return;
        default:
            ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
        }
    }
    private void Ins1_Handler(APDU apdu){
        Test_ServerInf sio = null;
        ServerAID=JCSystem.lookupAID(ServerAIDbyte,(short) 0,(byte) ServerAIDbyte.length);
        if(ServerAID==null)
            ISOException.throwIt( (short) 0x6A82);
        ////server request
        try{
        sio=(Test_ServerInf)(JCSystem.getAppletShareableInterfaceObject(ServerAID, (byte) 0));
        }
        catch(SecurityException e)
       {
           ISOException.throwIt((short)0x12);
       }
       catch(Exception e)
       {
           ISOException.throwIt((short)0x10);
       }
        if(sio==null)
            ISOException.throwIt((short)0x6A00);

    }

    private void Ins2_Handler(APDU apdu,byte[] apduBuffer){
            Test_ServerInf sio = null;
           ////connect to server  
          ServerAID=JCSystem.lookupAID(ServerAIDbyte,(short) 0,(byte) ServerAIDbyte.length);
           if(ServerAID==null)
                ISOException.throwIt( (short) 0x6A82);
           ////server request
           try{
               sio=(Test_ServerInf)(JCSystem.getAppletShareableInterfaceObject(ServerAID, (byte) 0));
           }
           catch(SecurityException e)
           {
               ISOException.throwIt((short)0x12);
           }
           catch(Exception e)
           {
               ISOException.throwIt((short)0x10);
           }
           if(sio==null)
                ISOException.throwIt((short)0x6A00); 
    }


}

And this is Server applet code (Test_Server.java):

  package server;

import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import server.Test_ServerInf;
import javacard.framework.Shareable;
import javacard.framework.AID;

public class Test_Server extends Applet implements Test_ServerInf{


    private Test_Server() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new Test_Server().register();
    }

    public void process(APDU apdu) throws ISOException {
        // TODO Auto-generated method stub

    }

    public Shareable getShareableInterfaceObject(AID clientAID, byte parameter) {
        return this;
    }

    public short method1(){
        return (short)0x01;
    }
    public short method2(){
        return (short)0x02;
    }

}

and the shareable interface file (Test_ServerInf.java):

package server;

import javacard.framework.Shareable;

public interface Test_ServerInf extends Shareable {

    public short method1();
    public short method2();

}

Answer:

You are trying to store a reference to the shareable interface object in a member field of your client applet class:

sio = (Test_ServerInf)(JCSystem.getAppletShareableInterfaceObject(ServerAID, (byte) 0));

where sio is defined as private member of the applet class instance:

public class Test_Client extends Applet {
    private Test_ServerInf sio;

This will result in a SecurityException since the shareable interface object is owned by the server applet (i.e. by a different context). You are not allowed to store objects owned by other contexts in an instance field.

See Accessing Class Instance Object Fields (Section 6.2.8.3), in Runtime Environment Specification, Java Card Platform, Version 2.2.2:

Bytecodes: getfield, putfield

  • [...] if the object is owned by an applet in the currently active context, access is allowed.
  • Otherwise, access is denied.

Question:

I face "java.net.UnknownServiceException: protocol doesn't support output" problem when I sent my name from applet to servlet. I tried Sending object to Servlet throws an error I cant resolve but it didn't solve my problem. My applet code is:

import java.io.*;

import javax.servlet.ServletException;
import javax.servlet.http.*;

public class AppletToServlet extends HttpServlet {
// Getting a String object from the applet and send it back.
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            response.setContentType("application/x-java-serialized-object");
            InputStream inputStream = request.getInputStream();
            ObjectInputStream inputFromApplet = new ObjectInputStream(inputStream);
            String string = (String) inputFromApplet.readObject();
// getting string value and passing to applet
OutputStream outputStream = response.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(string);
objectOutputStream.flush();
objectOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

and the servlet code is:

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

public class AppletToServletExample extends Applet {
  private TextField inputField = new TextField(10);
  private TextField resultField = new TextField(10);

  public void init() {
    // add input label, field and send button
    add(new Label("Input Your Name", Label.RIGHT));
    add(inputField);
    Button sendButton = new Button("Send");
    add(sendButton);
    sendButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        SendData();
      }
    });
    // add output label as a non editable field
    add(new Label("Output:", Label.RIGHT));
    add(resultField);
    resultField.setEditable(false);
  }

  // Get a connection to the servlet.
  private URLConnection getServletConnection() throws MalformedURLException,
      IOException {
    URL urlServlet = new URL(getCodeBase(), "applettoservlet");
    URLConnection con = urlServlet.openConnection();
    con.setDoInput(true);
    con.setDoOutput(true);
    con.setUseCaches(false);
    con.setRequestProperty("Content-Type",
        "application/x-java-serialized-object");
    return con;
  }

  // Send the inputField data to the servlet and show the result in the
  // outputField.
  private void SendData() {
    try {
      String input = inputField.getText();
      // send data to the servlet
      URLConnection con = getServletConnection();
      OutputStream outputStream = con.getOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(outputStream);
      oos.writeObject(input);
      oos.flush();
      oos.close();
      // receive result from servlet
      InputStream inputStream = con.getInputStream();
      ObjectInputStream inputFromServlet = new ObjectInputStream(
          inputStream);
      String result = (String) inputFromServlet.readObject();
      inputFromServlet.close();
      inputStream.close();
      // show result
      resultField.setText(result);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}

I searched practically everywhere but couldn't solve it.


Answer:

Where do you run the applet? Did you actually embed it onto a page and request it over a webserver of some kind?

The code

 URL urlServlet = new URL(getCodeBase(), "applettoservlet");

will only work as expected if you're running the applet from a page served by a web/application-server. Try adding

System.out.println(urlServlet);

to check what url is beeing used.

Question:

I am writing an applet that I eventually want to put online so that my friends/family can use it. I have the applet running now locally, but in order to work properly it needs to read a .ser file in when the applet opens, and update that same file when the applet closes. The file is quite large (~180 MB), though I am working on paring it down.

What would be the fastest/most effective way to read/write this file in java? There is a lot of information out there on this and I have never done anything like it before, so it's a bit overwhelming. The class HTTPURLConnection seems like an option to read it, but not write it. Any free web hosting that I have seen will not allow a file that big to be uploaded.

The size of the file should hopefully go down substantially, it is a list of 2.8 million musical artists, many of which I'm sure nobody using the program will ever encounter, but if this program is to be effective, many artists will have to be stored, so the problem most likely remains the same.

Thanks in advance for any help


Answer:

It sounds like it would be wise to keep this large data and the processing of it on your server instead of making the applet operate on it. That's because you would avoid each user downloading a large file and processing it. If you had a server side piece that the applet could call to get useful information from, then only your server would have to load it, write it, and process it. You could implement a Java servlet, or a PHP program to respond to http requests from your applet in a format that suits the data. I'm assuming that your server can handle either servlets or custom PHP (most can).

Question:

I trying to build a very small android app, just for my own use and knowledge, I've learned Java a few years ago, but now and i need some help. the app will use Google maps and will send the location to a server (can someone recommend on one?), that's all for the this app.

The main thing I would like to build is a screen which I can see all the users in it, this screen is planning to run on a PC, and that's the part i need you guys.

How should I build this screen? Is it supposed to be an applet? Maybe a Web application? Could it be something else? What should be the layout if I want to present the map on most of the screen and some buttons and text on the side/bottom? and where can i find examples and stuff on this subject?

Thanks a lot


Answer:

I think the easiest for you would be to make a simple HTTP java servlet. If you don't have a lot of experience, I would recommend using amazon's SimpleDB as your database, and hosting your servlet on one of aws' free services. You can find documentation online on how to manipulate your simpleDB from your java servlet, and how to talk to the servlet from your android client.This would be a good experience to learn about client-server stacks and http methods.

There are loads of ways to do this, but I recommend this as the simplest. I currently do something similar using a django framework (python) and a postgresql database hosted on heroku.

Question:

I'm just getting into networking and I'm quite confused about how I can use a server from a server hosting company for a game. At the moment, the program allows a user to host the server from their computer and it works to some degree. The only problem is that when my friends connect to the game from other states their ping is super high and they lag horribly.

I'm now using a site that gives out free web hosting space. I've believe I've jumped through most of the permission hoops that I need in order to use sockets and the applet works just like it does while running on my computer.

Below is an excerpt from the Game class. If I use InetAddress.getLocalHost().getHostAddress() to get the IP, it gets the IP from the user who is using the client and makes them the server host. This works, but it doesn't solve my problem of lag.

    Game.java

    public synchronized void start() {
    running = true;

    thread = new Thread(this, NAME + "_main");
    thread.start();

    if (JOptionPane.showConfirmDialog(this, "Do you want to run the server") == 0) {
        socketServer = new GameServer(this);
        socketServer.start();
    }


    this.ipAddress = "31.170.163.198";
    //this.ipAddress = InetAddress.getByName(ipAddress).toString();

    System.out.println("IP: " + this.ipAddress);
    socketClient = new GameClient(this, this.ipAddress);//Inet4Address.getLocalHost().getHostAddress());    

    try {
        Player.setIp(Inet4Address.getLocalHost().getHostAddress());
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
    socketClient.start();
}

I want the server that contains the jar to host the server. We all ping test each other and we mostly all get timed out, however, when we ping the server's ip we all get decent ping. When I enter the Server's IP (I find this info in the control panel) manually the server/client fail to make a connection. I've tried using both the website IP and the server IP that are provided. I've also tried using the applet.getCodeBase().getHost() in order to retrieve the IP from the server but that IP failed to send/receive data as well.

Is what I'm trying to do possible? Is the server blocking me from using it in that way? Do I need to rewrite the whole program and look into java servlets to achieve my goal?

I apologize if the question is silly. I've been working on this for the past 3-4 days with very little progress. I've searched around a bit on using a server in this manner and I've found very little on the topic.

Below are some excerpts from other relevant pieces of code.

GameClient.java

package fraccas.java2dgame.net;


public class GameClient extends Thread {

private InetAddress ipAddress;
private DatagramSocket socket;
private Game game;
public long lastPing = 0;
public static int ping = 0;

public GameClient(Game game, String ipAddress) {
    this.game = game;
    try {
        this.socket = new DatagramSocket();
        this.ipAddress = InetAddress.getByName(ipAddress);
        System.out.println("IP: " + InetAddress.getByName(ipAddress));
    } catch (SocketException e) {
        e.printStackTrace();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
}

public void run() {
    while (true) {
        byte[] data = new byte[1024];
        DatagramPacket packet = new DatagramPacket(data, data.length);
        try {
            socket.receive(packet);
            if (packet != null)
            {
                long current = System.currentTimeMillis();
                ping = (int) (current - lastPing);
                lastPing = current;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.parsePacket(packet.getData(), packet.getAddress(), packet.getPort());
    }
}

private void parsePacket(byte[] data, InetAddress address, int port) {
    String message = new String(data).trim();
    PacketTypes type = Packet.lookupPacket(message.substring(0, 2));
    Packet packet = null;
    switch (type) {
    default:
    case INVALID:
        break;
    case LOGIN:
        packet = new Packet00Login(data);
        handleLogin((Packet00Login) packet, address, port);
        break;
    case DISCONNECT:
        packet = new Packet01Disconnect(data);
        System.out.println("[" + address.getHostAddress() + ":" + port + "] "
                + ((Packet01Disconnect) packet).getUsername() + " has left the world...");
        game.level.removePlayerMP(((Packet01Disconnect) packet).getUsername());
        break;
    case MOVE:
        packet = new Packet02Move(data);
        handleMove((Packet02Move) packet);
    }
}

public void sendData(byte[] data) {
    //if (!game.isApplet) {
        DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress, 3333);
        try {
            socket.send(packet);
        } catch (IOException e) {
            e.printStackTrace();
        }
   //}
}

private void handleLogin(Packet00Login packet, InetAddress address, int port) {
    System.out.println("[" + address.getHostAddress() + ":" + port + "] " + packet.getUsername()
            + " has joined the game...");
    PlayerMP player = new PlayerMP(game.level, packet.getX(), packet.getY(), packet.getUsername(), address, port);
    game.level.addEntity(player);
}

private void handleMove(Packet02Move packet) {
    this.game.level.movePlayer(packet.getUsername(), packet.getX(), packet.getY(), packet.getNumSteps(),
            packet.isMoving(), packet.getMovingDir());
}

}

GameServer.java

package fraccas.java2dgame.net;


public class GameServer extends Thread {

private DatagramSocket socket;
private Game game;
private List<PlayerMP> connectedPlayers = new ArrayList<PlayerMP>();

public GameServer(Game game) {
    this.game = game;
    try {
        this.socket = new DatagramSocket(3333);
    } catch (SocketException e) {
        e.printStackTrace();
    }
}

public void run() {
    while (true) {
        byte[] data = new byte[1024];
        DatagramPacket packet = new DatagramPacket(data, data.length);
        try {
            socket.receive(packet);
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.parsePacket(packet.getData(), packet.getAddress(), packet.getPort());
    }
}

private void parsePacket(byte[] data, InetAddress address, int port) {
    String message = new String(data).trim();
    PacketTypes type = Packet.lookupPacket(message.substring(0, 2));
    Packet packet = null;
    switch (type) {
    default:
    case INVALID:
        break;
    case LOGIN:
        packet = new Packet00Login(data);
        System.out.println("[" + address.getHostAddress() + ":" + port + "] "
                + ((Packet00Login) packet).getUsername() + " has connected...");
        PlayerMP player = new PlayerMP(game.level, 100, 100, ((Packet00Login) packet).getUsername(), address, port);
        this.addConnection(player, (Packet00Login) packet);
        break;
    case DISCONNECT:
        packet = new Packet01Disconnect(data);
        System.out.println("[" + address.getHostAddress() + ":" + port + "] "
                + ((Packet01Disconnect) packet).getUsername() + " has left...");
        this.removeConnection((Packet01Disconnect) packet);
        break;
    case MOVE:
        packet = new Packet02Move(data);
        this.handleMove(((Packet02Move) packet));
    }
}

public void addConnection(PlayerMP player, Packet00Login packet) {
    boolean alreadyConnected = false;
    for (PlayerMP p : this.connectedPlayers) {
        if (player.getUsername().equalsIgnoreCase(p.getUsername())) {
            if (p.ipAddress == null) {
                p.ipAddress = player.ipAddress;
            }
            if (p.port == -1) {
                p.port = player.port;
            }
            alreadyConnected = true;
        } else {
            // relay to the current connected player that there is a new
            // player
            sendData(packet.getData(), p.ipAddress, p.port);

            // relay to the new player that the currently connect player
            // exists
            //packet = new Packet00Login(p.getUsername(), p.x, p.y);
            Packet00Login packetNew = new Packet00Login(p.getUsername(), p.x, p.y);
            sendData(packetNew.getData(), player.ipAddress, player.port);
        }
    }
    if (!alreadyConnected) {
        this.connectedPlayers.add(player);
    }
}

public void removeConnection(Packet01Disconnect packet) {
    this.connectedPlayers.remove(getPlayerMPIndex(packet.getUsername()));
    packet.writeData(this);
}

public PlayerMP getPlayerMP(String username) {
    for (PlayerMP player : this.connectedPlayers) {
        if (player.getUsername().equals(username)) {
            return player;
        }
    }
    return null;
}

public int getPlayerMPIndex(String username) {
    int index = 0;
    for (PlayerMP player : this.connectedPlayers) {
        if (player.getUsername().equals(username)) {
            break;
        }
        index++;
    }
    return index;
}

public void sendData(byte[] data, InetAddress ipAddress, int port) {
    //if (!game.isApplet) {

        DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress, port);
        try {
            this.socket.send(packet);
        } catch (IOException e) {
            e.printStackTrace();
        }
    //}
}

public void sendDataToAllClients(byte[] data) {
    for (PlayerMP p : connectedPlayers) {
        sendData(data, p.ipAddress, p.port);
    }
}

private void handleMove(Packet02Move packet) {
    if (getPlayerMP(packet.getUsername()) != null) {
        int index = getPlayerMPIndex(packet.getUsername());
        PlayerMP player = this.connectedPlayers.get(index);
        player.x = packet.getX();
        player.y = packet.getY();
        player.setMoving(packet.isMoving());
        player.setMovingDir(packet.getMovingDir());
        player.setNumSteps(packet.getNumSteps());
        packet.writeData(this);
    }
}

The applet does not have any errors in the console at the moment. It simply does not send/receive the data.

http://critterisland.bugs3.com/public_html/index.html (Applet Link) http://gyazo.com/a91401545b1a741f2b9fc86471bd5762 (Image of Applet)

Thanks for you time, Fraccas


Answer:

The problem is that you're using a web host which is only able to provide the files to users as opposed to actually being able to run the software you've created.

To run your software independently in the way you're wanting, your easiest option is to rent a virtual private server (VPS) which is located appropriately for your users. However, you'll need to be able to do some basic configuration on the VPS (such as install Java), and then run your server as a console application.

Not much code needs to be changed to get it working. You could use the same jar file for both the server and the client by adding a command line argument which only starts the server (i.e. "-server"). From the server computer/VPS you would then start the server by running "java -jar CritterIslandTest.jar -server" which then only starts the server and handles communication. If the command line argument is not found you can then continue with the GUI logic.

Question:

I came across System.getProperty("user.home") and System.getProperty("user.dir") in java, but those are returning paths from the server. I have an applet and want to create a folder based on the user directory on the client, is there any way to get that information?


Answer:

Here's how you can check which System properties are available in your applet:

  • Enable Java Console in your Java Settings (show console)

  • Run your applet. Java-Console should show up.

  • Press "s" to show your system properties and check for "user.home" value