package examples.ejb.basic.beanManaged; import javax.naming.*; import javax.ejb.*; import java.rmi.RemoteException; import java.util.Properties; /** * This class demonstrates calling an entity EJBean * using multiple colocated clients. *

* After finding the account and checking that its balance * is at least $1,000,000, multiple BigSenders are spawned and * let loose on the account. They withdraw money from the account, * demonstrating the capability of EJBeans to handle * multiple clients simultaneously. *

* This class also illustrates how to search the JNDI tree * for an appropriate container. * * @author Copyright (c) 1998 by WebLogic, Inc. All Rights Reserved. * @author Copyright (c) 1998-1999 by BEA WebXpress. All Rights Reserved. */ public class MultiClient { static final double amountToWithdraw = 1; static final int numSpenders = 10; static final int numWithdrawsPerSpender = 10; static String url = "t3://localhost:7001"; static String user = null; static String password = null; static String accountId = "10020"; /** * Runs this example from the command line. Example: *

* java examples.ejb.basic.beanManaged.MultiClient "t3://localhost:7001" scott tiger 10030 *

* The parameters are optional, but if any are supplied, * they are interpreted in this order: *

* @param url URL such as "t3://localhost:7001" of Server * @param user User name, default null * @param password User password, default null * @param accountID String Account ID to test, default "10020" */ public static void main(String[] args) { System.out.println("\nBeginning beanManaged.MultiClient...\n"); // Parse the argument list if ((args == null) || (args.length == 0)) {} else for (int i = 0; i < args.length; i++) { switch(i) { case 0: url = args[i]; break; case 1: user = args[i]; break; case 2: password = args[i]; break; case 3: accountId = args[i]; break; default: } } AccountPK accountKey = new AccountPK(); accountKey.accountId = accountId; try { // Contact the AccountBean container (the "AccountHome") through JNDI. Context ctx = getInitialContext(); AccountHome home = (AccountHome) ctx.lookup("beanManaged.AccountHome"); // Find the Account or create it. Account ac = null; try { ac = (Account) home.findByPrimaryKey(accountKey); } catch (Exception ee) { System.out.println("Did not find " + accountId); } double balance; if (ac == null) { System.out.println("Account " + accountId + " being created"); ac = home.create(accountId, /*initial balance = */ 1000000); balance = 1000000; } else { balance = ac.balance(); // Check the balance if the account was found. if (balance < 1000000) { ac.deposit(1000000 - balance); balance = ac.balance(); } } System.out.println("Before balance: $" + ac.balance()); double expectedBalance = balance - (numSpenders * numWithdrawsPerSpender * amountToWithdraw); System.out.println("Expected balance after all " + numSpenders + " MultiClientBigSpender threads complete: $" + expectedBalance + "\n"); MultiClientBigSpender[] spenders = new MultiClientBigSpender[numSpenders]; for (int i = 0; i < numSpenders; i++) { spenders[i] = new MultiClientBigSpender(i, ac); spenders[i].start(); } for (int i = 0; i < numSpenders; i++) { try { spenders[i].join(0); } catch (Exception e) { System.out.println("::::::::::::: Thread Join Error :::::::::::::::::\n" + e); } } balance = ac.balance(); if (expectedBalance == balance) { System.out.println("Successful completion.\nBalance = $" + balance); } else { System.out.println("::::::::::::::::::: Failure :::::::::::::::::::::"); System.out.println("Expected balance = $" + expectedBalance + ", Actual balance = $" + balance); } } catch (ProcessingErrorException pe) { System.out.println("Processing Error: " + pe); } catch (Exception e) { System.out.println(":::::::::::::: Unexpected Error :::::::::::::::::\n"); e.printStackTrace(); } finally { System.out.println("\nEnd beanManaged.MultiClient..."); } } /** * Gets an initial context for the current user, password and url. * * @return Context * @exception java.lang.Exception if there is * an error in getting the Context */ static public Context getInitialContext() throws Exception { Properties p = new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); p.put(Context.PROVIDER_URL, url); if (user != null) { System.out.println ("user: " + user); p.put(Context.SECURITY_PRINCIPAL, user); if (password == null) password = ""; p.put(Context.SECURITY_CREDENTIALS, password); } return new InitialContext(p); } } /** * This class creates the MultiClientBigSpender threads used by * MultiClient. * * @author Copyright (c) 1998 by WebLogic, Inc. All Rights Reserved. * @author Copyright (c) 1998-1999 by BEA WebXpress. All Rights Reserved. * @see MultiClient */ class MultiClientBigSpender extends Thread { int id; Account ac; /** * Creates a MultiClientBigSpender with an ID and * an account. * * @param id int ID * @param ac Account Account * @see MultiClient#main */ public MultiClientBigSpender(int i, Account ac) { this.id = i; this.ac = ac; } /** * Runs a MultiClientBigSpender and makes it * withdraw money from its account. * @see MultiClient#main */ public void run() { try { for (int i = 0; i < MultiClient.numWithdrawsPerSpender; i++) { ac.withdraw(MultiClient.amountToWithdraw); } } catch (Exception e) { System.out.println("Aborting thread " + id + ": " + weblogic.utils.StackTraceUtils.throwable2StackTrace(e)); } } }