How can I call an EJB3 session bean in a JSP? - java

I am developing an application in Eclipse using EJBs and JPA.
My Session bean is :
package itso.bank.session;
import itso.bank.entities.Account;
import itso.bank.entities.Customer;
import itso.bank.entities.Transaction;
import itso.bank.exception.ITSOBankException;
import itso.bank.service.EJBBankService;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.*;
/**
* Session Bean implementation class EJBBankBean
*/
#Stateless
public class EJBBankBean implements EJBBankService {
#PersistenceContext (unitName="RAD8JPA", type=PersistenceContextType.TRANSACTION)
private EntityManager entityMgr;
/**
* Default constructor.
*/
public EJBBankBean() {
// TODO Auto-generated constructor stub
}
public void addCustomer(Customer customer) throws ITSOBankException {
System.out.println("addCustomer: " + customer.getSsn());
entityMgr.persist(customer);
}
public void closeAccount(String ssn, String id) throws ITSOBankException {
System.out.println("closeAccount: " + id + " of customer " + ssn);
Account account = getAccount(id);
Transaction[] trans = getTransactions(id);
for (Transaction tx : trans) {
entityMgr.remove(tx);
}
entityMgr.remove(account);
System.out.println("closed account with " + trans.length + " transactions");
}
public void deleteCustomer(String ssn) throws ITSOBankException {
System.out.println("deleteCustomer: " + ssn);
Customer customer = getCustomer(ssn);
Account[] accounts = getAccounts(ssn);
for (Account acct : accounts) {
closeAccount(ssn, acct.getId());
}
entityMgr.remove(customer);
}
public void deposit(String id, BigDecimal amount) throws ITSOBankException {
System.out.println("deposit: " + id + " amount " + amount);
Account account = getAccount(id);
try {
Transaction tx = account.processTransaction(amount, Transaction.CREDIT);
entityMgr.persist(tx);
} catch (Exception e) {
throw new ITSOBankException(e.getMessage());
}
}
public Account getAccount(String id) throws ITSOBankException {
System.out.println("getAccount: " + id);
try {
return entityMgr.find(Account.class, id);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
throw new ITSOBankException(id);
}
}
public Account[] getAccounts(String ssn) throws ITSOBankException {
System.out.println("getAccounts: " + ssn);
Query query = null;
try {
query = entityMgr.createNamedQuery("getAccountsBySSN");
query.setParameter(1, ssn);
List<Account> accountList = query.getResultList();
Account[] array = new Account[accountList.size()];
return accountList.toArray(array);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
throw new ITSOBankException(ssn);
}
}
public Customer getCustomer(String ssn) throws ITSOBankException {
System.out.println("getCustomer: " + ssn);
//Query query = null;
try {
//query = entityMgr.createNamedQuery("getCustomerBySSN");
//query.setParameter(1, ssn);
//return (Customer)query.getSingleResult();
return entityMgr.find(Customer.class, ssn);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
throw new ITSOBankException(ssn);
}
}
public Customer[] getCustomers(String partialName) throws ITSOBankException {
System.out.println("getCustomer: " + partialName);
Query query = null;
try {
query = entityMgr.createNamedQuery("getCustomersByPartialName");
query.setParameter(1, partialName);
List<Customer> beanlist = query.getResultList();
Customer[] array = new Customer[beanlist.size()];
return beanlist.toArray(array);
} catch (Exception e) {
throw new ITSOBankException(partialName);
}
}
public Customer[] getCustomersAll() {
System.out.println("getCustomers: all");
Query query = null;
try {
query = entityMgr.createNamedQuery("getCustomers");
List<Customer> beanlist = query.getResultList();
Customer[] array = new Customer[beanlist.size()];
return beanlist.toArray(array);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
return null;
}
}
public Transaction[] getTransactions(String accountID) throws ITSOBankException {
System.out.println("getTransactions: " + accountID);
Query query = null;
try {
query = entityMgr.createNamedQuery("getTransactionsByID");
query.setParameter(1, accountID);
List<Transaction> transactionsList = query.getResultList();
Transaction[] array = new Transaction[transactionsList.size()];
return transactionsList.toArray(array);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
e.printStackTrace();
throw new ITSOBankException(accountID);
}
}
public String openAccount(String ssn) throws ITSOBankException {
System.out.println("openAccount: " + ssn);
Customer customer = getCustomer(ssn);
int acctNumber = (new java.util.Random()).nextInt(899999) + 100000;
String id = "00" + ssn.substring(0, 1) + "-" + acctNumber;
Account account = new Account();
account.setId(id);
entityMgr.persist(account);
List<Customer> custSet = Arrays.asList(customer);
account.setCustomers(custSet);
System.out.println("openAccount: " + id);
return id;
}
public void transfer(String idDebit, String idCredit, BigDecimal amount) throws ITSOBankException {
System.out.println("transfer: " + idCredit + " " + idDebit + " amount " + amount);
withdraw(idDebit, amount);
deposit(idCredit, amount);
}
public void updateCustomer(String ssn, String title, String firstName, String lastName) throws ITSOBankException {
System.out.println("updateCustomer: " + ssn);
Customer customer = getCustomer(ssn);
customer.setTitle(title);
customer.setLastName(lastName);
customer.setFirstName(firstName);
System.out.println("updateCustomer: " + customer.getTitle() + " " + customer.getFirstName() + " " + customer.getLastName());
}
public void withdraw(String id, BigDecimal amount) throws ITSOBankException {
System.out.println("withdraw: " + id + " amount " + amount);
Account account = getAccount(id);
try {
Transaction tx = account.processTransaction(amount, Transaction.DEBIT);
entityMgr.persist(tx);
} catch (Exception e) {
throw new ITSOBankException(e.getMessage());
}
}
}
My JPA is already connected to the EJB project. My question is how I call the session bean from a Java Server Page, without the need for servlets?
Thank you!

Simply, Annotate Service Implementation class by #Named annotation
#Stateless
#Named("eJBBankBean")
public class EJBBankBean implements EJBBankService {....}
In your JSP file, use:
#{ejbBankBean.yourServiceMethod(parameter1_ifAny,parameter2_ifAny)}
#Named is CDI Annotation, without #Named EJB Bean will not visible in JSP EL i.e. '$' or Unified EL i.e. '#'

I suppose there must be a reason for not using an MVC framework.
So, supposing you are using a local interface, this is the cleanest and standard way I remember for invoking an ejb from a .jsp
<ejb-local-ref>
<ejb-ref-name>MyBeanName</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.myapp.ejb.MyBeanLocal</local>
</ejb-local-ref>
Then from your jsp
<%
String lookupUrl = "java:comp/env/MyBeanName";
Context ctx = new javax.naming.InitialContext();
MyBeanNameLocal ejbLocal = (MyBeanNameLocal) ctx.lookup(lookupUrl);
String output = ejbLocal.myBusinessMethod();
%>

Related

Spring 5 does not support old Classes. How can I upgrade project?

I have just upgraded Spring dependencies to version 5.3.23 and noticed that class SimpleJdbcDaoSupport and ParameterizedRowMapper are not supported any more. Then how can I accommodate my code upgrading with Spring 5.x?
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
public class TestDataAccessDao extends SimpleJdbcDaoSupport {
#SuppressWarnings("deprecation")
public List<WbClientPU> findClientcodeByPUname(String PUname) {
final List<WbClientPU> list = new ArrayList<WbClientPU>();
String sql = "select * from WISEBANKNEXTAC.dbo.WB_CLIENTPU c where c.PUName='"
+ PUname + "'";
try {
return getSimpleJdbcTemplate().query(sql,
new ParameterizedRowMapper<WbClientPU>() {
public WbClientPU mapRow(ResultSet rs, int row)
throws SQLException {
String pacsCode = rs.getString(1);
String puname = rs.getString(2);
String clientCode = rs.getString(3);
WbClientPU clntPu = new WbClientPU();
clntPu.setPacsCode(pacsCode);
clntPu.setPuName(puname);
clntPu.setClientCode(clientCode);
list.add(clntPu);
return clntPu;
}
});
} catch (Exception e1) {
e1.printStackTrace();
}
System.out.println("===== PU List : " + list);
return list;
}
...
.....
}

BitcoinJ wallet shows wrong balance

I'm getting familiar with BitcoinJ. So now there is a function for user that registers for the first time and there should be created address for him. But it doesn't work. It says there is already some money.
// USER HAS NEVER USED COIN_ATLAS ( IT IS THE FIRST TIME )
public void addUser()
{
DBObject dbUser;
WalletAppKit kit = new WalletAppKit(TestNet3Params.get(), new File("."), "forwarding-service-testnet");
params = TestNet3Params.get();
Debug.Log("Wait a bit...");
kit.startAsync();
kit.awaitRunning();
BlockChain chain = null;
my_wallet = kit.wallet(); // Wallet created for that user
try {
chain = new BlockChain(params, my_wallet,
new MemoryBlockStore(params));
} catch (BlockStoreException e) {
e.printStackTrace();
}
PeerGroup peerGroup = new PeerGroup(params, chain);
peerGroup.addPeerDiscovery(new DnsDiscovery(params));
peerGroup.addWallet(my_wallet);
peerGroup.startAsync();
Debug.Log("WALLET: " + my_wallet.currentReceiveAddress());
Debug.Log("WALLET BALANCE: " + my_wallet.getBalance().toFriendlyString());
my_wallet.addCoinsReceivedEventListener(new WalletCoinsReceivedEventListener() {
#Override
public void onCoinsReceived(Wallet wallet, Transaction transaction, Coin coin, Coin coin1) {
send("NEW TRANSACTION:");
sendWithMarkdown("FROM: " + wallet.currentReceiveAddress() + " : " + bold(coin1.toFriendlyString()));
Coin value = transaction.getValueSentToMe(wallet);
System.out.println("Received tx for " + value.toFriendlyString() + ": " + transaction);
Futures.addCallback(transaction.getConfidence().getDepthFuture(1), new FutureCallback<TransactionConfidence>() {
#Override
public void onSuccess(#Nullable TransactionConfidence transactionConfidence) {
send(bold("Transaction confirmed!"));
send(bold(value.toFriendlyString() + " is deposited!"));
}
#Override
public void onFailure(Throwable throwable) {
}
});
}
});
peerGroup.downloadBlockChain();
peerGroup.stopAsync();
dbUser = new BasicDBObject("_id", bot_user.getId())
.append("firstName", bot_user.getFirstName())
.append("password", bot_user.getPassword())
.append("address", my_wallet.currentReceiveAddress().toString())
.append("BTC", (double)my_wallet.getBalance().getValue());
collection.insert(dbUser);
}
There is what I get in output:
WALLET: mtrjbnpq5wDzoywrKqod63tpB7ZUFrr7q5
WALLET BALANCE: 1.21503904 BTC
But if I check this address in blockchain, it shows 0.
So how to create wallet the right way?

QuickBooks NULL CallbackHandler

I'm trying to perform a batch operation in QuickBook but getting null callbackhandler.
private static void AddBulkCustomer(DataService ds) throws FMSException{
BatchOperation bo = new BatchOperation();
Customer c1 = new Customer();
c1.setGivenName("Customer 3");
c1.setDisplayName("Disp Customer 3");
EmailAddress email = new EmailAddress();
email.setAddress("customer1#zzz.com");
c1.setPrimaryEmailAddr(email);
bo.addEntity(c1, OperationEnum.CREATE, "b3");
c1= null;
c1 = new Customer();
c1.setGivenName("Customer 4");
c1.setDisplayName("Disp Customer 4");
email = null;
email = new EmailAddress();
email.setAddress("customer2#z2zz.com");
c1.setPrimaryEmailAddr(email);
bo.addEntity(c1, OperationEnum.CREATE, "b4");
// String strQuery = " select * from customer where givenname ='"+c1.getGivenName()+"'";
// bo.addQuery(strQuery, "b3Query");
ds.executeBatchAsync(bo, new AsyncCallBackBatch());
}
For AsyncCallback operation
public class AsyncCallBackBatch implements CallbackHandler {
#Override
public void execute(CallbackMessage callbackMsg) {
System.out.println("asyncCallbackBatch is executing... ");
try {
System.out.println("QR = "+callbackMsg.getFMSException().toString());
BatchOperation BO = callbackMsg.getBatchOperation();
if (BO != null) {
List<String> bId = BO.getBIds();
for (String strBId : bId) {
if (BO.isFault(strBId)) {
Fault fault = BO.getFault(strBId);
System.out.println("asyncCallBackBatch Error Code : "+ fault.getError().get(0).getCode() + " "+ "Error : "
+ fault.getError().get(0).getDetail()+ ", Message : "+ fault.getError().get(0).getMessage());
} else if (BO.isEntity(strBId)) {
System.out.println("Batch having entity message.. ");
Customer cust = (Customer) BO.getEntity(strBId);
System.out.println("cust id : " + cust.getId()+ " CustName = " + cust.getGivenName());
} else if (BO.isQuery(strBId)) {
System.out.println("Batch having Query ... Parsing... ");
QueryResult qR = BO.getQueryResponse(strBId);
System.out.println("Query : " + qR.getTotalCount());
} else if (BO.isReport(strBId)) {
System.out.println("Batch having Report... ");
Report report = BO.getReport(strBId);
System.out.println(" " + report.getClass().getName());
} else {
System.out.println("Something went wrong... ");
}
}
}else{
System.out.println("Batch Operation terminated, reason: NULL callbackMsg ");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
OAuthAuthorizer oAuth = new OAuthAuthorizer(consumerKey, consumerSecret, accessToken, accessTokenSecret);
//403352746
try {
Context context = new Context(oAuth, ServiceType.QBO, "403352746");
System.out.println("RealmID : "+context.getRealmID());
context.setCustomerRequestTimeout(99999);
System.out.println("TimeOut Set to = "+context.getCustomerRequestTimeout());
System.out.println("BASE_URL_QBO = "+Config.getProperty(Config.BASE_URL_QBO));
Config.setProperty(Config.BASE_URL_QBO, "https://sandbox-quickbooks.api.intuit.com/v3/company");
System.out.println("BASE_URL_QBO = "+Config.getProperty(Config.BASE_URL_QBO));
DataService ds = new DataService(context);
AddBulkCustomer(ds);
System.out.println("Operation Complete..");
} catch (Exception e) {
e.printStackTrace();
}
}
When I debug, in execute method, I'm getting Null BatchOperation in return. I'm not sure performing Batch operation is allowed in sandbox environment.
I found the solution after so much of testing and communication with Quickbooks Devs thought would be helpful for others.
In sandbox environment even if you set the config properties to sandbox URL it still picks as PROD URL in Callbackhandler.
Config.setProperty(Config.BASE_URL_QBO, "https://sandbox-quickbooks.api.intuit.com/v3/company");
In this case they called this as a bug, currently all you can do is to make a trial account in PROD and then test this.

Exception when saving a result

I am developping J2EE application with appfuse , i have a webform called easyVolAction that contain a method search() I need to save the result of search method in database but and an excpetion is generated when clicking in the action search :NullPointerException in object trajet .I created TrajetDaoHibernate:
public TrajetDaoHibernate() {
super(TrajetModel.class);
}
/**
* {#inheritDoc}
*/
#SuppressWarnings("unchecked")
public List<TrajetModel> getTrajet() {
Session session = getSessionFactory().getCurrentSession();
Query qry = session.createQuery("from TrajetModel u order by upper(u.id)");
return qry.list();
}
/**
* {#inheritDoc}
*/
public TrajetModel saveTrajet(TrajetModel trajet) {
if (log.isDebugEnabled()) {
log.debug("user's id: " + trajet.getId());
}
Session session = getSessionFactory().getCurrentSession();
session.saveOrUpdate(trajet);
// necessary to throw a DataIntegrityViolation and catch it in UserManager
session.flush();
return trajet;
}
#Override
public TrajetModel save(TrajetModel trajet) {
return this.saveTrajet(trajet);
}
and TrajetDao:
public interface TrajetDao extends GenericDao {
List<TrajetModel> getTrajet();
TrajetModel saveTrajet(TrajetModel trajet);
}
and trajetManager:
#Service("trajetManager")
public class TrajetModelImpl extends GenericManagerImpl<TrajetModel, Long> implements TrajetManager {
private TrajetDao trajetDao;
#Autowired
public void setTrajetModelDao(TrajetDao trajetDao) {
this.dao = trajetDao;
this.trajetDao = trajetDao;
}
/**
* {#inheritDoc}
*/
public TrajetModel getTrajet(String trajetId) {
return trajetDao.get(new Long(trajetId));
}
/**
* {#inheritDoc}
*/
public List<TrajetModel> getTrajet() {
return trajetDao.getAllDistinct();
}
/**
* {#inheritDoc}
*/
public TrajetModel saveTrajet(TrajetModel trajet) throws TrajetExistsException {
try {
return trajetDao.saveTrajet(trajet);
} catch (DataIntegrityViolationException e) {
//e.printStackTrace();
log.warn(e.getMessage());
throw new TrajetExistsException("Trajet '" + trajet.getNom() + "' already exists!");
} catch (JpaSystemException e) { // needed for JPA
//e.printStackTrace();
log.warn(e.getMessage());
throw new TrajetExistsException("Trajet '" + trajet.getNom() + "' already exists!");
}
}
}
finnaly the action where i declare the search method:
public String recherche() throws IOException, TrajetExistsException {
HttpServletRequest request = (HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest();
// String url1 =
// FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("hidden");
String departAller = request.getParameter("easyVolRobot:villeDepart");
String arriveeAller = request.getParameter("easyVolRobot:villeArrivee");
String jourAller = request.getParameter("easyVolRobot:jourDep");
String moisAller = request.getParameter("easyVolRobot:dateDep");
String jourRetour = request.getParameter("easyVolRobot:jourDep");
String moisRetour = request.getParameter("easyVolRobot:dateArr");
String jourAllerPlus1 = jourAller + 1;
parametre = "departAller=" + departAller + "&arriveeAller="
+ arriveeAller + "&jourAller=" + jourAller + "&moisAller="
+ moisAller + "&jourRetour=" + jourRetour + "&moisRetour="
+ moisRetour;
parametre1 = "departAller=" + departAller + "&arriveeAller="
+ arriveeAller + "&jourAller=" + jourAllerPlus1 + "&moisAller="
+ moisAller + "&jourRetour=" + jourRetour + "&moisRetour="
+ moisRetour;
String response = sendGetRequest(url, parametre);
// insert();
PrintStream out = null;
try {
out = new PrintStream(new FileOutputStream(
"/data/crawl/root/siteSNCF.html"));
out.print(response);
} finally {
if (out != null)
out.close();
}
// tableau de resultats des trajets
List<TrajetModel> listTrajets = new ArrayList<TrajetModel>();
// trajet
//TrajetModel trajet = new TrajetModel();
File input = new File("/data/crawl/root/siteSNCF.html");
Document doc = Jsoup.parse(input, "UTF-8",
"http://www.easyvols.org/france-voyage");
for (Element vol : doc.select("div.vols")) {
//trajet = new TrajetModel();
for (Element allerRetour : vol.select("div.aller-retour")) {
Elements aeroport = allerRetour.select("div.aeroport");
System.out.println(aeroport.text());
Elements depart = allerRetour.select("div.depart");
Elements arrive = allerRetour.select("div.arrivee");
Elements date = allerRetour.select("div.date");
trajet.setNom(aeroport.text());
trajet.setVilleDepart(depart.text());
trajet.setVilleArrive(arrive.text());
trajet.sethArrive(12);
trajet.sethDepart(11);
trajet.sethReqt(14);
}
Elements prix2 = vol.select("div.tarif");
trajet.setPrice(prix2.text());
trajet = trajetManager.saveTrajet(trajet);
System.out.println(trajet);}
return"mainMenu";
}
why you comment this line out?
//TrajetModel trajet = new TrajetModel();
I see no other line where you create the TrajetModel.
If that object is not initiated you get the NPE here:
trajet.setNom(aeroport.text());

asynccallback failures

In my app I need to add string vallues to the file(.property file, if it is important). and user enter this values in gwt GUI. Here is it's important part:
final Button submit = new Button("Submit");
addButton(submit);
submit.addSelectionListener(new SelectionListener<ButtonEvent>() {
#Override
public void componentSelected(ButtonEvent ce) {
keyWord.selectAll();
regexp.selectAll();
if (keyWord.getValue() != null){
setKeyWord(customerId, keyWord.getValue());
keyWord.setValue("");
}
if (regexp.getValue() != null){
setRegExp(customerId, regexp.getValue());
regexp.setValue("");
}
}
});
}
private void setKeyWord(final String customerId, final String keyword){
final AsyncCallback<String> callbackItems = new AsyncCallback<String>() {
public void onFailure(final Throwable caught) {
Window.alert("unable to add " + caught.toString());
}
public void onSuccess(final String x) {
Window.alert(x);
}
};
serverManagementSvc.setKeyWords(customerId, keyword, callbackItems);
}
private void setRegExp(final String customerId, final String regexp){
final AsyncCallback<String> calbackItems = new AsyncCallback<String>() {
#Override
public void onFailure(Throwable throwable) {
Window.alert("unable to add " + throwable.toString());
}
#Override
public void onSuccess(String s) {
Window.alert(s);
}
};
serverManagementSvc.setRegExp(customerId, regexp, calbackItems);
}
So I need to use Asunccallback to call methods which are in the "server part".
here are these methods:
//adds a new keyword to customers properties
public String setKeyWords(String customer, String word){
try{
PropertiesConfiguration props = new PropertiesConfiguration("/home/mikhail/bzrrep/DLP/DLPServer/src/main/resources/rules.properties");
String newKeyWord = new String(props.getString("users." + customer + ".keywords" + "," + word));
props.setProperty("users." + customer + ".keywords", newKeyWord);
props.save();
}catch (ConfigurationException e){
e.printStackTrace();
}
return "keyword " + word + " added";
}
// adds a new regexp to customer properties
public String setRegExp(String customer, String regexp){
try {
PropertiesConfiguration props = new PropertiesConfiguration("/home/mikhail/bzrrep/DLP/DLPServer/src/main/resources/rules.properties");
String newRegValue = new String(props.getString("users." + customer + ".regexps" + "," + regexp));
props.setProperty("users." + customer + ".regexps", newRegValue);
props.save();
} catch (ConfigurationException e){
e.printStackTrace();
}
return "regexp " + regexp + " added to " + customer + "'s config";
}
all interfaces are present.
when I run my code And press "submit" button in gui I see that both asynccallback failured(Window.alert, as you can see, shows "null pointer exception" despite of the fact that values which I send to methods are not null). why can it be? can you suggest me something?
UPD here is error which is shown by firebug:
uncaught exception: java.lang.ClassCastException
function W8(){try{null.a()}catch(a){return a}}
the problem is solved: there were a simple mistake in the code. I've closed brackets at the wrong place:
//adds a new keyword to customers properties
public String setKeyWords(String customer, String word){
try{
PropertiesConfiguration props = new PropertiesConfiguration("/home/mikhail/bzrrep/DLP/DLPServer/src/main/resources/rules.properties");
String newKeyWord = new String(props.getString("users." + customer + ".keywords") + "," + word);
props.setProperty("users." + customer + ".keywords", newKeyWord);
props.save();
}catch (ConfigurationException e){
e.printStackTrace();
}
return "keyword " + word + " added";
}
// adds a new regexp to customer properties
public String setRegExp(String customer, String regexp){
try {
PropertiesConfiguration props = new PropertiesConfiguration("/home/mikhail/bzrrep/DLP/DLPServer/src/main/resources/rules.properties");
String newRegValue = new String(props.getString("users." + customer + ".regexps") + "," + regexp);
props.setProperty("users." + customer + ".regexps", newRegValue);
props.save();
} catch (ConfigurationException e){
e.printStackTrace();
}
return "regexp " + regexp + " added to " + customer + "'s config";
}
I recommend that you recompile the GWT code using
-style PRETTY
and then check that firebug output again; it may give you a better clue, compared to your updated uncaught exception.
Next, I suggest you run it in the eclipse debugger, and set breakpoints in both the client and server code, and then you can inspect the variables and step through the code.

Categories

Resources