I am trying to understand TCP for my Project. I have to make a game with Network in which client can watch the main player. For that I send the state data over tcp .
But after I initialze one ChatClient and call the method set() in ChatClient I got error.
I cant figure out how to solve it.
package control;
import javafx.application.Platform;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ChatClient extends Thread {
// TextField nachricht;
ObjectInputStream ii;
ChatScreen chat;
GameScreen gamescreen;
Socket socket;
String name;
ObjectOutputStream i;
public ChatClient (String name, ChatScreen chat, GameScreen gamescreen) {
this.chat = chat;
this.gamescreen = gamescreen;
this.name = name;
}
#Override
public void run() {
// Diese Methode wird ausgeführt, wenn ein Client-Thread startet
// Baue eine Verbindung zum entfernten Rechner auf
try (Socket socket = new Socket("localhost", 9004)) {
System.out.println(name);
// this.chat.getButton().setText("w");
// Öffne einen InputStream
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
i = new ObjectOutputStream(out);
ii = new ObjectInputStream(in);
String line;
try {
line = (String) ii.readObject();
System.out.print("text");
if (line != null) {
Platform.runLater(() -> {
gamescreen.getText().appendText(line + "\n");
});
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
public GameScreen getGameScreen() {
return gamescreen;
}
public void set() {
Platform.runLater(() -> {
try {
i.writeObject(name + ":" + chat.nachricht.getText() + "\n");
i.close();
} catch (IOException e) {
System.out.print("ws");
e.printStackTrace();
}
});
}
}
Server:
package control;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
/**
* Server for class {#link de.kaiguenster.javaintro.client.Client}, that handles all connections in their own Threads
*
* #author Kai Günster
*/
public class MultithreadedServer {
static ArrayList<ObjectOutputStream> client = new ArrayList<>();
private static int port = 9004;
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(port);
// this loop runs until the program is shut down (e.g. using `CTRL+C`)
while (true) {
// wait for connection
Socket sock = server.accept();
// When a connection is accepted, handle it in a new Thread
new Thread(new AntwortProzess(sock)).start();
}
}
/**
* Create a server Server
*
* #param port
* Listen-Port
*/
private MultithreadedServer (int port) {
this.port = port;
}
private static void sendMessage(String nachricht) {
}
/**
* Wait for connection and process it.
*
* #throws IOException
*/
/**
* Runnable, to process incomming connections
*/
private static class AntwortProzess extends Thread {
private final Socket socket;
public AntwortProzess (Socket socket) {
this.socket = socket;
}
#Override
public void run() {
// Diese Methode wird vom Thread gerufen, wenn er startet.
try (Socket socket = this.socket) {
System.out.print("true");
/*
Wait 2 seconds first. This waiting priod happend in it's own
Thread and doesn't prevent other connections to be accepted.
*/
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
ObjectOutputStream i = new ObjectOutputStream(out);
ObjectInputStream ii = new ObjectInputStream(in);
client.add(i);
while (true) {
String line = (String) ii.readObject();
if (line != null) {
for (int b = 0; b < client.size(); b++) {
try {
client.get(b).writeObject(line + "\n");
// System.out.print(line);
client.get(b).flush();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
// Write one line of text back to the client.
} catch (IOException | ClassNotFoundException ex) {
System.out.println(ex);
}
}
}
}
Error:
java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.ObjectInputStream$PeekInputStream.peek(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.peek(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at control.ChatClient.run(ChatClient.java: 59)
Related
I implemented SignalR Java Client in my Android Project. It works well on Android Versions 6 to 11 but fails on Android 12, I'm getting this error only on Android 12 java.net.SocketException: Socket closed [Ljava.lang.StackTraceElement;#e95116d, here is my code:
import android.content.Context;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.microsoft.signalr.HubConnection;
import com.microsoft.signalr.HubConnectionBuilder;
import com.microsoft.signalr.OnClosedCallback;
import org.json.JSONObject;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import timber.log.Timber;
public class SignalRChatService {
Timer timer = new Timer();
public void startTimer()
{
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// Your code here
Timer_Elapsed();
}
}, 1000, 2000);
}
private void Timer_Elapsed()
{
try
{
module.checkNetwork(context);
if(!Connected)
{
Init();
}
}
catch (Exception e)
{
Connected = false;
}
}
private HubConnection _connection;
public boolean Connected;
public String instanceName;
public int instanceProfileId;
private boolean connecting;
private SignalRMessageReceivedEvents signalRMessageReceivedEvents;
private final Gson gson;
private final Context context;
public SignalRChatService(Context context, String instanceName, int instanceProfileId, SignalRMessageReceivedEvents signalRMessageReceivedEvents) {
this.instanceName = instanceName;
this.instanceProfileId = instanceProfileId;
this.connecting = false;
this.context = context;
this.signalRMessageReceivedEvents = signalRMessageReceivedEvents;
gson = new GsonBuilder().setPrettyPrinting().create();
}
public void Stop()
{
try
{
_connection.stop();
}
catch(Exception ignored)
{}
}
public void Init()
{
if (connecting)
{
return;
}
try
{
connecting = true;
_connection = HubConnectionBuilder.create("https://" + instanceName.trim().toLowerCase() + ".com").build();
try
{
_connection.start();
Connected = true;
}
catch (Exception e)
{
Connected = false;
Timber.e("SignalR Push connect: %s", e.getLocalizedMessage());
return;
}
_connection.on("Message", (message) ->
{
try
{
// Separate this code affterwads
JSONObject messageObject = new JSONObject(message);
String Messagetype = (String) messageObject.get("messageType");
HandleWebSocketMessage(Messagetype, message);
}
catch (Exception ignored)
{
}
}, String.class);
_connection.onClosed(new OnClosedCallback() {
#Override
public void invoke(Exception exception) {
handleClosed();
}
});
}
catch (Exception ignored)
{
}
finally
{
connecting = false;
startTimer();
}
}
private void handleClosed()
{
try
{
TimeUnit.MILLISECONDS.sleep(100);
}
catch (Exception ignored)
{
}
Init();
}
}
I've tried upgrading to the latest version of SignalR Java Client
implementation "com.microsoft.signalr:signalr:6.0.3"
and it is still not working. It just wont receive any Signal.
I don't know what will be the fix to the error cause I already mentioned the column names and I have a name column in my database.(I am just a beginner) please help me.
This is my DbH class
package sjdb.db;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created by user on 30/09/2016.
*/
public class DbH extends SQLiteOpenHelper {
private Context mycontext;
private String DB_PATH = "/data/data/sjdb.db/databases/";
private static String DB_NAME = "red.db";
private static String DB_TABLE="form";
public static String Col_1="name";
public static String Col_2="address";
public static String Col_3="number";
public SQLiteDatabase myDataBase;
/*private String DB_PATH = "/data/data/"
+ mycontext.getApplicationContext().getPackageName()
+ "/databases/";
*/
public DbH(Context context) throws IOException {
super(context,DB_NAME,null,1);
this.mycontext=context;
}
public void createdatabase() throws IOException{
boolean dbexist = checkdatabase();
if(dbexist)
{
System.out.println(" Database exists.");
}
else{
this.getReadableDatabase();
try{
copydatabase();
}
catch(IOException e){
throw new Error("Error copying database");
}
}
}
private boolean checkdatabase() {
//SQLiteDatabase checkdb = null;
boolean checkdb = false;
try{
String myPath = DB_PATH + DB_NAME;
File dbfile = new File(myPath);
checkdb = SQLiteDatabase.openDatabase(myPath,null,SQLiteDatabase.OPEN_READWRITE) != null;
checkdb = dbfile.exists();
}
catch(SQLiteException e){
System.out.println("Database doesn't exist");
}
return checkdb;
}
private void copydatabase() throws IOException {
//Open your local db as the input stream
InputStream myinput = mycontext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outfilename = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myoutput = new FileOutputStream(outfilename);
// transfer byte to inputfile to outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myinput.read(buffer))>0)
{
myoutput.write(buffer,0,length);
}
//Close the streams
myoutput.flush();
myoutput.close();
myinput.close();
}
public void opendatabase() throws SQLException
{
//Open the database
String mypath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READONLY);
}
public synchronized void close(){
if(myDataBase != null){
myDataBase.close();
}
super.close();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// This will return a cursor containing database records
public Cursor data(){
Cursor c;
String[] from = new String[] {Col_1, Col_2, Col_3};
c=myDataBase.query(DB_TABLE,from,null, null,null,null,null);
return c;
}
#Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
}
}
And this is my MyActivity class
package sjdb.db;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
public class MyActivity extends Activity implements View.OnClickListener {
/** Called when the activity is first createdl. */
Cursor cur;
TextView tv, tv1, tv2;
DbH db;
Button next,back;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
tv=(TextView)findViewById(R.id.text);
tv1=(TextView)findViewById(R.id.text1);
tv2=(TextView)findViewById(R.id.text2);
next=(Button)findViewById(R.id.next);
back=(Button)findViewById(R.id.back);
next.setOnClickListener(this);
back.setOnClickListener(this);
try {
db=new DbH(this);
} catch (IOException e2) {
e2.printStackTrace();
}
try {
db.createdatabase();
} catch (IOException e) {
e.printStackTrace();
}
db.opendatabase();
cur=db.data();
cur.moveToFirst();
tv.setText(cur.getString(1));
tv1.setText(cur.getString(2));
tv2.setText(cur.getString(3));
}
#Override
public void onClick(View v) {
switch(v.getId())
{
case R.id.next :
if(cur.isLast())
{
cur.moveToFirst();
tv.setText(""+cur.getString(1));
tv1.setText(""+cur.getString(2));
tv2.setText(""+cur.getString(3));
}
else
{
cur.moveToNext();
tv.setText(""+cur.getString(1));
tv1.setText(""+cur.getString(2));
tv2.setText(""+cur.getString(3));
}
break;
case R.id.back:
{
if(cur.isFirst())
{
cur.moveToLast();
tv.setText(""+cur.getString(1));
tv1.setText(""+cur.getString(2));
tv2.setText(""+cur.getString(3));
}
else {cur.moveToPrevious();
tv.setText(""+cur.getString(1));
tv1.setText(""+cur.getString(2));
tv2.setText(""+cur.getString(3));
}
break;
}
}
}
}
This is the error:
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{sjdb.db/sjdb.db.MyActivity}: android.database.sqlite.SQLiteException: no such column: name: , while compiling: SELECT name, address, number FROM form
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1970)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
at android.app.ActivityThread.access$600(ActivityThread.java:128)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4517)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.sqlite.SQLiteException: no such column: name: , while compiling: SELECT name, address, number FROM form
at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:68)
at android.database.sqlite.SQLiteProgram.compileSql(SQLiteProgram.java:143)
at android.database.sqlite.SQLiteProgram.compileAndbindAllArgs(SQLiteProgram.java:361)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:127)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:94)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:53)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1686)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1571)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1527)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1607)
at sjdb.db.DbH.data(DbH.java:122)
at sjdb.db.MyActivity.onCreate(MyActivity.java:47)
at android.app.Activity.performCreate(Activity.java:4470)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1053)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1934)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
at android.app.ActivityThread.access$600(ActivityThread.java:128)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4517)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
at dalvik.system.NativeStart.main(Native Method)
I/Process: Sending signal. PID: 11719 SIG: 9
column: name: , while compiling: SELECT name, address, number FROM form
Try looking these part. Are these correct?
Try to fit this code if it doesnt go to your TextView.
I am making an IRC client in a javafx fxml project.
I am having difficulties understanding the structure of the project. I get the MVC pattern however i don't know where i have to position the main code part of the client(object initialisation and communication start).
I want to be able to update a textarea with a String from a serverConnection object when the server sends a message.
So where do i position the code and how do i notify my controller that it has to update its text passing the String simultaneously?
This is the application class:
package jircclient;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.util.concurrent.*;
public class JircClient extends Application
{
#Override
public void start(Stage stage) throws Exception
{
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setTitle("jircClient");
stage.setScene(scene);
stage.show();
System.out.println("Stage SET!");
//This is where i thought that i could write the main part of the program
//but the stage will not load unless the start method finishes
//Creating a serverConnetion is not a problem since it's only an object
//but starting the communication does not let the method we are in to exit
//since it sticks in a while loop forever until i probably cancel it using a
//button (not implemented yet)
//serverConnection server1 = new serverConnection();
//server1.startCommunication();
}
public static void main(String[] args) throws Exception
{
//In this method i cannot go further unless i close the stage-window
//The purpose of it is to launch the start method
Application.launch(args);
}
}
This is the controller class:
package jircclient;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextArea;
public class FXMLDocumentController implements Initializable
{
#FXML
private TextArea txt;
#FXML
private void handleButtonAction(ActionEvent event)
{
//In here i will be handling events, however i will need to have
//access to serverConnection objects
System.out.println("You clicked me!");
}
#Override
public void initialize(URL url, ResourceBundle rb)
{
}
}
This is the serverConnection class:
package jircclient;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
public class serverConnection
{
//VARIABLES
private clientInfo client;
private String server_to_connect = "someserver";
private String channel_to_connect = "#somechannel";
private String serv_resp;
private int port = 6667;
private Socket socket;
private BufferedWriter writer;
private BufferedReader reader;
private ArrayList<channel> channels;
//DEFAULT CONSTRUCTOR
public serverConnection() {client = new clientInfo("test1", "test1", "test1");}
//FULL CONSTRUCTOR
public serverConnection(String server_to_connect, int port, String channel_to_connect) throws IOException
{
client = new clientInfo("test1", "test1", "test1");
this.server_to_connect = server_to_connect;
this.port = port;
this.channel_to_connect = server_to_connect;
try
{
//Creating socket connection
this.socket = new Socket(this.server_to_connect,port);
//Socket output writer
writer = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
//Socket input writer
reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
serv_resp = null;
System.out.println("Connection established.");
}
catch(UnknownHostException exc)
{
System.out.println("ERROR: "+ exc.toString());
}
catch(IOException exc)
{
System.out.println("ERROR: "+ exc.toString());
}
finally
{
System.out.println("Closing connection.");
socket.close();
}
}
//server response getter
public String getServerResponse()
{
return serv_resp;
}
//Introduction to server and listen
public void startCommunication() throws IOException
{
this.socket = new Socket(this.server_to_connect,port);
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
serv_resp = null;
writer.write("NICK " + client.getClientNickname() + "\r\n");
writer.write("USER " + client.getClientLogin() + " 0 * : " +
client.getClientRealName() + "\r\n");
while ((serv_resp = reader.readLine()) != null)
{
System.out.println(serv_resp);
//FXMLDocumentController.txt.setText(serv_resp);
if (serv_resp.indexOf("004") >= 0)
{
break;
}
else if (serv_resp.indexOf("433") >= 0)
{
System.out.println("Nickname is already in use.");
return;
}
}
//Get channel list
writer.write("LIST \r\n");
writer.flush();
//Join desired client
writer.write("JOIN " + channel_to_connect + "\r\n");
writer.flush();
//keep listening
while ((serv_resp = reader.readLine()) != null)
{
//FXMLDocumentController.txt.setText(serv_resp);
if (serv_resp.startsWith("PING "))
{
this.pingPong();
} else
{
System.out.println(serv_resp);
}
}
}
//Ping respond
public void pingPong() throws IOException
{
writer.write("PONG " + serv_resp.substring(5) + "\r\n");
writer.flush();
}
}
I believe there is no need to add the fxml document since it's big and there is no need.
I also have to state that oracle tutorials were not helpful as they only use the event handling in the controller and they don't implement any other logic.
Here is one possible way to do this:
Give your ServerConnection class a callback to call when it receives a message:
public class ServerConnection {
private Consumer<String> messageCallback ;
public void setMessageCallback(Consumer<String> messageCallback) {
this.messageCallback = mesasgeCallback ;
}
// other fields and methods as before...
public void startCommunication() throws IOException {
// code as before ...
while ((servResp = reader.readLine()) !=null) {
if (messageCallback != null) {
messageCallback.accept(servResp);
}
// etc....
}
// etc
}
}
Now instantiate your ServerConnection class from the controller and pass it a callback:
public class FXMLDocumentController {
ServerConnection serverConnection ;
// ...
public void initialize() {
serverConnection = new ServerConnection();
serverConnection.setMessageCallback(message ->
Platform.runLater(() -> txt.appendText(message+"\n")));
Thread serverThread = new Thread(() -> serverConnection.startListening());
serverThread.setDaemon(true); // thread will not stop application from exiting
serverThread.start();
}
// ...
}
the contest is: TomEE 7.0 with openEjb 4.7.1. I'm try to create an instance of an Entity Bean, EJB Entity 2.1 BMP (Bean Managed Persistence).
The Deploy of the bean work fine, also the creating of the remote home interface on a client example application, but when i try to create an istance of the entity bean, an error occur.
The code of the Entity is:
Home interface BmpEntityHome.java
package it.enzo.ejb.entity.bmp;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
import javax.ejb.FinderException;
public interface BmpEntityHome extends EJBHome {
//Metodo Creazione
public BmpEntityBean createObject(String id) throws RemoteException, CreateException;
//Metodo finder
public BmpEntityBean findByPrimaryKey(String key) throws RemoteException, FinderException;
//Metodo di logica personalizzato
//public int getMetodoPersonalizzato() throws RemoteException;
}
Remote interface BmpEntityObject.java
package it.enzo.ejb.entity.bmp;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface BmpEntityObject extends EJBObject{
public String getId() throws RemoteException;
public void setId(String id) throws RemoteException;
public String getValore1() throws RemoteException;
public void setValore1(String x) throws RemoteException;
public String getValore2() throws RemoteException;
public void setValore2(String x) throws RemoteException;
public int getAddizzione() throws RemoteException;
//Metodo di logica
//public void addizziona(int a, int b) throws RemoteException;
}
Bean interface BmpEntityBean.java
package it.enzo.ejb.entity.bmp;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;
public class BmpEntityBean implements EntityBean{
private static final long serialVersionUID = 1L;
private EntityContext ectx;
private String iD;
private String valore1;
private String valore2;
private int addizzione;
//Costruttore
public BmpEntityBean(){
System.out.println("BmbRntityBean chiamato il costruttore");
}
//Metodo di business
public void addizziona(int a, int b){
this.addizzione = a + b;
}
//Metodi getter e setter
public String getId() {
return iD;
}
public void setId(String iD) {
this.iD = iD;
}
public String getValore1() {
return valore1;
}
public void setValore1(String valore1) {
this.valore1 = valore1;
}
public String getValore2() {
return valore2;
}
public void setValore2(String valore2) {
this.valore2 = valore2;
}
public int getAddizzione() {
return addizzione;
}
//Metodo privato per creare la connessione al DB
private Connection getConnection(){
Connection cnn = null;
try {
Class.forName("org.sqlite.JDBC");
cnn = DriverManager.getConnection("jdbc:sqlite:EJBdatabase.db");
this.CreaTabelle(cnn);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return cnn;
}
private void CreaTabelle(Connection cnn){
Statement stat = null;
try {
stat = cnn.createStatement();
stat.executeUpdate("CREATE TABLE if not exists BmpEntityBeanTable (id string primary key, valore1 string, valore2 string, addizzione integer)");
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//Metodo finder
public String ejbFindByPrimaryKey(String key) throws FinderException{
PreparedStatement pstm = null;
Connection cnn = null;
try{
cnn = this.getConnection();
pstm = cnn.prepareStatement("SELECT id FROM BmpEntityBeanTable WHERE id = ?");
pstm.setString(1, key);
ResultSet rs = pstm.executeQuery();
if(rs.next())return key;
}catch(Exception e){e.printStackTrace();}
finally{
try {
pstm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
throw new FinderException("Entity con id "+key+" non Trovato");
}
//Metodo personalizzato sull'oggetto Home
//public int ejbHomeGetMetodoPersonalizzato(){
//return 2976;
//}
//Metodi di callback richiamati dal container
//Metodo di creazione
public BmpEntityBean ejbCreateObject(String id) throws CreateException{
Connection cnn = null;
PreparedStatement pstm = null;
this.iD = id;
try{
cnn = this.getConnection();
pstm = cnn.prepareStatement("INSERT INTO BmpEntityBeanTable (id) values ('"+id+"')");
pstm.execute();
return this;
}catch(Exception e){e.printStackTrace();}
finally{
try {
pstm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
throw new CreateException();
}
#Override
public void setEntityContext(EntityContext ctx) throws EJBException,
RemoteException {
// TODO Auto-generated method stub
this.ectx = ctx;
}
#Override
public void unsetEntityContext() throws EJBException, RemoteException {
// TODO Auto-generated method stub
this.ectx = null;
}
#Override
public void ejbRemove() throws RemoveException, EJBException,
RemoteException {
// TODO Auto-generated method stub
String key = (String) this.ectx.getPrimaryKey();
String id = key;
Connection cnn = null;
PreparedStatement pstm = null;
try{
cnn = this.getConnection();
pstm = cnn.prepareStatement("DELETE FROM BmpEntityBeanTable WHERE id = ?");
pstm.setString(1, id);
pstm.execute();
}catch(Exception e){e.printStackTrace();}
finally{
try {
pstm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void ejbActivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
#Override
public void ejbPassivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
#Override
public void ejbLoad() throws EJBException, RemoteException {
// TODO Auto-generated method stub
String key = (String) this.ectx.getPrimaryKey();
String id = key;
Connection cnn = null;
PreparedStatement pstm = null;
try{
cnn = this.getConnection();
pstm = cnn.prepareStatement("SELECT * FROM BmpEntityBeanTable WHERE id = ?");
pstm.setString(1, id);
ResultSet rs = pstm.executeQuery();
if(rs.next()){
this.iD = id;
this.valore1 = rs.getString("valore1");
this.valore2 = rs.getString("valore2");
this.addizzione = rs.getInt("addizzione");
}
rs.close();
}catch(Exception e){e.printStackTrace();}
finally{
try {
pstm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void ejbStore() throws EJBException, RemoteException {
// TODO Auto-generated method stub
String key = (String) this.ectx.getPrimaryKey();
String id = key;
Connection cnn = null;
PreparedStatement pstm = null;
try{
cnn = this.getConnection();
pstm = cnn.prepareStatement("UPDATE BmpEntityBeanTable set valore1 = ?, valore2 = ?, addizione = ? WHERE id = ?");
pstm.setString(1, this.valore1);
pstm.setString(2, this.valore2);
pstm.setInt(3, this.addizzione);
pstm.setString(4, id);
pstm.execute();
}catch(Exception e){e.printStackTrace();}
finally{
try {
pstm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Deploy desciptor ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
version="2.1">
<enterprise-beans>
<entity>
<ejb-name>BmpEntity</ejb-name>
<home>it.enzo.ejb.entity.bmp.BmpEntityHome</home>
<remote>it.enzo.ejb.entity.bmp.BmpEntityObject</remote>
<ejb-class>it.enzo.ejb.entity.bmp.BmpEntityBean</ejb-class>
<persistence-type>Bean</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>false</reentrant>
<primkey-field>iD</primkey-field>
</entity>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>BmpEntity</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
Client Example application
package it.enzo;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import javax.ejb.CreateException;
import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ProvaServ
*/
#WebServlet("/ProvaServ")
public class ProvaServ extends HttpServlet {
private static final long serialVersionUID = 1L;
private it.enzo.ejb.entity.bmp.BmpEntityHome bmpEntityHome = null;
public ProvaServ() {
super();
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String comm = request.getParameter("comm");
if(comm!=null){
switch(comm.toString()){
case "bmpEntity_Start":
this.bmpEntityHome = null;
this.callBmpEntity();
break;
case "bmpEntity_Create":
if(this.bmpEntityHome!=null){
try {
String id = request.getParameter("id");
//it.enzo.ejb.entity.bmp.BmpEntityBean bmpEntityBean_TMP =
this.bmpEntityHome.createObject(id);
out.print("BmpEntity aggiunto: ");//+bmpEntityBean_TMP.getId());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
}
}
out.print("<div><form action=''>"
+"<input type='hidden' name='comm' value='bmpEntity_Create'>"
+"Aggiungi un BmpEntity <input type='text' name='id' value='ID-DELL-ENTITY-1'>"
+"<input type='submit' value='Aggiungi'>"
+"</form></div>");
out.print("<br><br><a href='?comm=bmpEntity_Start'>Start BMPEntity</a><br>");
}
private void callBmpEntity(){
if(this.bmpEntityHome==null){
Properties p = new Properties();
p.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
p.put("java.naming.provider.url", "http://localhost:8080/tomee/ejb");
InitialContext initialContext;
Object object = null;
try {
initialContext = new InitialContext(p);
object = initialContext.lookup("BmpEntityRemoteHome");
this.bmpEntityHome = (it.enzo.ejb.entity.bmp.BmpEntityHome)
PortableRemoteObject.narrow(object, it.enzo.ejb.entity.bmp.BmpEntityHome.class);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
the stack error
nov 23, 2014 9:36:48 AM org.apache.openejb.core.transaction.EjbTransactionUtil handleSystemException
GRAVE: EjbTransactionUtil.handleSystemException: object is not an instance of declaring class
java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.openejb.core.entity.EntityContainer.createEJBObject(EntityContainer.java:340)
at org.apache.openejb.core.entity.EntityContainer.invoke(EntityContainer.java:182)
at org.apache.openejb.server.ejbd.EjbRequestHandler.doEjbHome_CREATE(EjbRequestHandler.java:420)
at org.apache.openejb.server.ejbd.EjbRequestHandler.processRequest(EjbRequestHandler.java:187)
at org.apache.openejb.server.ejbd.EjbDaemon.processEjbRequest(EjbDaemon.java:344)
at org.apache.openejb.server.ejbd.EjbDaemon.service(EjbDaemon.java:240)
at org.apache.openejb.server.ejbd.EjbServer.service(EjbServer.java:86)
at org.apache.openejb.server.httpd.ServerServlet.service(ServerServlet.java:58)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
java.rmi.RemoteException: The bean encountered a non-application exception; nested exception is:
java.lang.IllegalArgumentException: object is not an instance of declaring class
at org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException(EjbTransactionUtil.java:155)
at org.apache.openejb.core.entity.EntityContainer.handleException(EntityContainer.java:484)
at org.apache.openejb.core.entity.EntityContainer.createEJBObject(EntityContainer.java:369)
at org.apache.openejb.core.entity.EntityContainer.invoke(EntityContainer.java:182)
at org.apache.openejb.server.ejbd.EjbRequestHandler.doEjbHome_CREATE(EjbRequestHandler.java:420)
at org.apache.openejb.server.ejbd.EjbRequestHandler.processRequest(EjbRequestHandler.java:187)
at org.apache.openejb.server.ejbd.EjbDaemon.processEjbRequest(EjbDaemon.java:344)
at org.apache.openejb.server.ejbd.EjbDaemon.service(EjbDaemon.java:240)
at org.apache.openejb.server.ejbd.EjbServer.service(EjbServer.java:86)
at org.apache.openejb.server.httpd.ServerServlet.service(ServerServlet.java:58)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.openejb.core.entity.EntityContainer.createEJBObject(EntityContainer.java:340)
... 25 more
The error origin in the class EntityContainer.class of the package openejb-core-4.7.1.jar
....
protected ProxyInfo createEJBObject(final Method callMethod, final Object[] args, final ThreadContext callContext, final InterfaceType type) throws OpenEJBException {
final BeanContext beanContext = callContext.getBeanContext();
callContext.setCurrentOperation(Operation.CREATE);
/*
* According to section 9.1.5.1 of the EJB 1.1 specification, the "ejbPostCreate(...)
* method executes in the same transaction context as the previous ejbCreate(...) method."
*
* For this reason the TransactionScopeHandler methods usally preformed by the invoke( )
* operation must be handled here along with the call explicitly.
* This ensures that the afterInvoke() is not processed between the ejbCreate and ejbPostCreate methods to
* ensure that the ejbPostCreate executes in the same transaction context of the ejbCreate.
* This would otherwise not be possible if container-managed transactions were used because
* the TransactionScopeManager would attempt to commit the transaction immediately after the ejbCreate
* and before the ejbPostCreate had a chance to execute. Once the ejbPostCreate method execute the
* super classes afterInvoke( ) method will be executed committing the transaction if its a CMT.
*/
final TransactionPolicy txPolicy = createTransactionPolicy(beanContext.getTransactionType(callMethod, type), callContext);
EntityBean bean = null;
Object primaryKey = null;
try {
// Get new ready instance
bean = instanceManager.obtainInstance(callContext);
// Obtain the proper ejbCreate() method
final Method ejbCreateMethod = beanContext.getMatchingBeanMethod(callMethod);
//HERE THE ERROR
// invoke the ejbCreate which returns the primary key
primaryKey = ejbCreateMethod.invoke(bean, args);//HERE THE ERROR
didCreateBean(callContext, bean);
// determine post create callback method
final Method ejbPostCreateMethod = beanContext.getMatchingPostCreateMethod(ejbCreateMethod);
// create a new context containing the pk for the post create call
final ThreadContext postCreateContext = new ThreadContext(beanContext, primaryKey);
postCreateContext.setCurrentOperation(Operation.POST_CREATE);
final ThreadContext oldContext = ThreadContext.enter(postCreateContext);
try {
// Invoke the ejbPostCreate method on the bean instance
ejbPostCreateMethod.invoke(bean, args);
// According to section 9.1.5.1 of the EJB 1.1 specification, the "ejbPostCreate(...)
// method executes in the same transaction context as the previous ejbCreate(...) method."
//
// The bean is first insterted using db.create( ) and then after ejbPostCreate( ) its
// updated using db.update(). This protocol allows for visablity of the bean after ejbCreate
// within the current trasnaction.
} finally {
ThreadContext.exit(oldContext);
}
// update pool
instanceManager.poolInstance(callContext, bean, primaryKey);
} catch (final Throwable e) {
handleException(txPolicy, e, callContext, bean);
} finally {
afterInvoke(txPolicy, callContext);
}
return new ProxyInfo(beanContext, primaryKey);
}
....
When i try this in the client example:
....
this.bmpEntityHome.createObject(id);
....
in the class EntityContainer.class of the package openejb-core-4.7.1.jar is called this method:
...
protected ProxyInfo createEJBObject(final Method callMethod, final Object[]...
...
and at the line 340 the instruction:
...
// invoke the ejbCreate which returns the primary key
primaryKey = ejbCreateMethod.invoke(bean, args);
...
generate the exception:
...
EjbTransactionUtil.handleSystemException: object is not an instance of declaring class
...
Thank!
Resolved... i have missed the 'ejbPostCreate' method in BmpEntityBean.class class (Business class)....
I have written a Netty server which sends asynchronous messages. The server is working as expected.
I can telnet to the server with a couple of telnet sessions and the asynchronous messages gets written out.
I have written a Netty Client but the client seems to be event driven and not asynchronous. On the server when the client connects; the server writes back to the client "Welcome" and the messages get handled in the client by the messageReceived event, any asynchronous event does not fire any event within the SimpleChannelHandler.
Question: How do I get the Netty client to pick up asynchronous message/events? At the moment it is event driven.
Just to add, the client is the Netty Telnet client.[http://netty.io/docs/stable/xref/org/jboss/netty/example/telnet/package-summary.html]
The Server Code
//---------Server code---------------
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
public class TestServer {
private final ServerBootstrap clientServerBootstrap;
private EchoServerFactory echoServerFactory;
private Channel appChannel;
public TestServer() {
this.clientServerBootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
this.clientServerBootstrap.setOption("child.tcpNoDelay", true);
}
public static void main(String[] args) {
try {
TestServer test = new TestServer();
test.start();
for(int i = 0; i < 100; i++) {
long time = System.currentTimeMillis()+1000;
String data = "setPhase();d(1,1,2.2342,"+time+");";
System.out.println(data);
test.write(data);
Thread.sleep(1000);
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
public void start() {
echoServerFactory = new EchoServerFactory();
clientServerBootstrap.setPipelineFactory(echoServerFactory);
InetSocketAddress isaApp = new InetSocketAddress("127.0.0.1", 9090);
appChannel = clientServerBootstrap.bind(isaApp);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
stop();
}
}));
}
public void write(String message) throws Exception {
echoServerFactory.write(message);
}
public void stop() {
clientServerBootstrap.releaseExternalResources();
}
}
//---------------Factory----------------------------
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.Delimiters;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
public class EchoServerFactory implements ChannelPipelineFactory {
EchoServerHandler handler = new EchoServerHandler();
public EchoServerHandler getHandler() {
return handler;
}
public void write(String message) throws Exception {
handler.write(message);
}
public ChannelPipeline getPipeline() throws Exception {
// Create a default pipeline implementation.
ChannelPipeline pipeline = org.jboss.netty.channel.Channels.pipeline();
// Add the text line codec combination first,
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());
// and then business logic.
pipeline.addLast("handler", handler);
return pipeline;
}
}
//---------------Handler----------------------------
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ChildChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.WriteCompletionEvent;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
public class EchoServerHandler extends SimpleChannelHandler {
private static final Logger logger = Logger.getLogger(EchoServerHandler.class.getName());
static final ChannelGroup channels = new DefaultChannelGroup();
public void write(String message) throws Exception {
channels.write(message);
}
#Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
Channel channel = e.getChannel();
channels.add(channel);
channel.write("Welcome\n\n");
}
#Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// Unregister the channel from the global channel list
// so the channel does not receive messages anymore.
//channels.remove(e.getChannel());
}
#Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
// Send back the received message to the remote peer.
System.out.println("------------------------->"+e.getMessage());
Channel ch = e.getChannel();
ChannelFuture f = ch.write(e.getMessage());
/* f.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) {
Channel ch = future.getChannel();
System.out.println("Completed : "+ch.isOpen());
}
});*/
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
// Close the connection when an exception is raised.
logger.log(
Level.WARNING,
"Unexpected exception from downstream.",
e.getCause());
e.getChannel().close();
}
}
The Client Code
//---------------- Client Code -------------------
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jfree.ui.RefineryUtilities;
/**
* Simplistic telnet client.
*/
public class TelnetClient {
private final String host;
private final int port;
public TelnetClient(String host, int port) {
this.host = host;
this.port = port;
}
public void run() throws IOException {
// Configure the client.
ClientBootstrap bootstrap = new ClientBootstrap(
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
// Configure the pipeline factory.
bootstrap.setPipelineFactory(new TelnetClientPipelineFactory());
bootstrap.setOption("tcpNoDelay", true);
// Start the connection attempt.
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
// Wait until the connection attempt succeeds or fails.
Channel channel = future.awaitUninterruptibly().getChannel();
if (!future.isSuccess()) {
future.getCause().printStackTrace();
bootstrap.releaseExternalResources();
return;
}
// Read commands from the stdin.
ChannelFuture lastWriteFuture = null;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
for (;;) {
String line = in.readLine();
if (line == null) {
break;
}
// Sends the received line to the server.
lastWriteFuture = channel.write(line + "\r\n");
// If user typed the 'bye' command, wait until the server closes
// the connection.
if (line.toLowerCase().equals("bye")) {
channel.getCloseFuture().awaitUninterruptibly();
break;
}
}
// Wait until all messages are flushed before closing the channel.
if (lastWriteFuture != null) {
lastWriteFuture.awaitUninterruptibly();
}
// Close the connection. Make sure the close operation ends because
// all I/O operations are asynchronous in Netty.
channel.close().awaitUninterruptibly();
// Shut down all thread pools to exit.
bootstrap.releaseExternalResources();
}
public static void main(String[] args) throws Exception {
try {
// Parse options.
String host = "127.0.0.1";
int port = 9090;
new TelnetClient(host, port).run();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
//---------------- Client Factory -------------------
import static org.jboss.netty.channel.Channels.*;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.Delimiters;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
/**
* Creates a newly configured {#link ChannelPipeline} for a new channel.
*/
public class TelnetClientPipelineFactory implements ChannelPipelineFactory {
public ChannelPipeline getPipeline() throws Exception {
// Create a default pipeline implementation.
ChannelPipeline pipeline = pipeline();
// Add the text line codec combination first,
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(1118192, Delimiters.lineDelimiter()));
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());
// and then business logic.
pipeline.addLast("handler", new TelnetClientHandler2());
return pipeline;
}
}
//----------------- Client handler -------------------
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ChildChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.WriteCompletionEvent;
/**
* Handles a client-side channel.
*/
public class TelnetClientHandler extends SimpleChannelHandler {
private static final Logger logger = Logger.getLogger(TelnetClientHandler.class.getName());
#Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
System.out.println("messageReceived");
String message = (String) e.getMessage();
parseMessage(message);
}
private void parseMessage(String message) {
try {
System.out.println("Messatge --> "+message);
} catch (Exception ex) {
ex.printStackTrace();
}
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
System.out.println(e.getCause());
logger.log(Level.WARNING,"Unexpected exception from downstream.", e.getCause());
e.getChannel().close();
}
}
Since you are using delimiter based frame decoder in the Netty Client App, it expects the delimiter at end of each message, but it looks like the server is not sending message with delimiter.
String data = "setPhase();d(1,1,2.2342,"+time+");";
System.out.println(data);
test.write(data);
after above messages are sent, frame decoder is keep waiting even after it received many messages. It works in telnet because, telnet session expects one character at a time. You have done it correctly only for the first message.
channel.write("Welcome\n\n");