My Java applet connects to mysql database on localhost for testing purposes. It works fine when I run it from eclipse, but it can't access db via browser. I wanted to know is it because browsers just don't support localhost db for some reason or I have problems with my code. And if browsers just don't support it, is it possible to test it somehow without uploading on the server ?
-
The problem is likely security related. Check the Java Console for errors. If the applet & (DB/servlet to access DB) are from the same host, and the applet uses the correct way to form a connection, it can be deployed sand-boxed.Andrew Thompson– Andrew Thompson2012-06-04 01:39:09 +00:00Commented Jun 4, 2012 at 1:39
-
3This is a really bad architecture, even if you jump through the necessary hoops to get it to work. You should never let code on remote systems have direct access to your database. Write a servlet to handle the specific operations you need to expose and have the applet interact with the servlet.Jim Garrison– Jim Garrison2012-06-04 05:51:24 +00:00Commented Jun 4, 2012 at 5:51
-
In case it is not entirely clear from my comments to duffymo, Do not allow the applet to have direct access to the DB. That is a recipe for disaster. Instead create a servlet (PHP/ASP/..whatever) that mediates access to the DB, and limits what a user can do.Andrew Thompson– Andrew Thompson2012-06-04 10:26:38 +00:00Commented Jun 4, 2012 at 10:26
2 Answers
The reason why is because your applet does not have the security permissions to access local ports on the computer. Java does this to protect peoples computers. Think about if you opened up a webpage and the Applet was allowed to access your local ports. You could have your computer hacked in seconds.
If you want to do it the way you're doing it, you need to package your applet in a jar file, sign it and verify it so that it can receive those permissions. Here is some info for you if you're interested:
How to create a jar file
How to sign and verify a jar file
How to run jar packaged software
All of those are great resources if thats the approach you want to take. What i would do is setup a Servlet (see duffymo's answer) or setup a ProxyServer to relay the information between your computer and the applet. If you want any more information let me know and i can provide it.
Edit:
This is sort of a lot of code but i think you will get the idea, i hope this helps. You of course will have to write the client end that connects to the server and requests information from the database.
DatabaseServer.java:
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.Iterator;
public class DatabaseServer implements Runnable
{
public DatabaseServer()
{
System.out.println("Created new server!");
clients = new ArrayList<Client>(); // this is a list of all the clients connected to the server
connected = false;
running = false;
connect(); // starts server
}
public void run()
{
System.out.println("Waiting for clients.../n");
while(running)
{
try
{
Socket socket = server.accept(); // waits for a client to connect
System.out.println("Client connected! "+socket.getInetAddress());
Client client = new Client(this, socket); // creates a new client object
clients.add(client);// adds it to the list
// cleans the client list everytime a new client connects
Iterator<Client> it = clients.iterator();
while(it.hasNext())
{
Client next = it.next();
if(!next.connected)
{
next.disconnect();
it.remove();
}
}
}catch(IOException e){e.printStackTrace();}
}
}
public void connect()
{
if(!connected)
{
System.out.println("starting server...");
try
{
System.out.println("opening port...");
server = new ServerSocket(8080); // opens a server socket
System.out.println("server started on port: "+server.getLocalPort());
running = true;
connected = true;
thread = new Thread(this);// starts the server thread
thread.start();
}catch(Exception e){e.printStackTrace(); connected = false; running = false;}
}
}
public void disconnect()
{
//stops the server
try
{
server.close();
}catch(Exception e){e.printStackTrace();}
server = null;
if(thread != null)
thread.interrupt();
thread = null;
connected = false;
running = false;
}
public void handleMessage(Client client, String message)
{
/* this is where you do your database interactions, based on the message you can pull out specific
* information from your database and then send it back to the client using client.sendMessage()
*/
}
private Thread thread;
private boolean running;
private boolean connected;
private ServerSocket server;
private ArrayList<Client> clients;
public static void main(String args[])
{
new DatabaseServer(); // makes a new server
}
}
Client.java:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client implements Runnable
{
public Client(DatabaseServer server, Socket socket)
{
this.socket = socket;
this.server = server;
try
{
connected = true;
writer = new PrintWriter(socket.getOutputStream()); // opens an output stream
reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // opens an input stream
running = true;
thread = new Thread(this);
thread.start();// starts the client thread
}catch(Exception e){e.printStackTrace(); connected = false;}
}
public void run()
{
try
{
String message = "";
while((message = reader.readLine()) != null & running & connected) // waits for a message to be recieved
{
server.handleMessage(this, message); // tells server to handle message
}
}catch(IOException e){e.printStackTrace(); connected = false;}
}
public void disconnect()
{
// disconnects client
try
{
socket.close();
}catch(Exception e){e.printStackTrace();}
try
{
reader.close();
}catch(Exception e){e.printStackTrace();}
try
{
writer.close();
}catch(Exception e){e.printStackTrace();}
socket = null;
reader = null;
writer = null;
if(thread != null)
thread.interrupt();
thread = null;
connected = false;
running = false;
}
public void sendMessage(String message)
{
// sends a message back to the client
writer.println(message);
writer.flush();
}
public boolean connected;
private boolean running;
private Thread thread;
private DatabaseServer server;
private Socket socket;
private PrintWriter writer;
private BufferedReader reader;
}
Your applet will connect to this server, and then you can send messages to the server to request information from the database. All you have to do is add the mysql stuff to the server and then write the client portion of your applet. Good luck!
3 Comments
I'd recommend putting a servlet between the applet and the database. You should not expose the database to the web like that. Better to have the applet send requests to the servlet and let it intercede on its behalf. The servlet can authenticate and authorize, validate and bind inputs, and marshall the response to send back.