| 1 25 26 27 package org.objectweb.jonas.resource; 28 29 import java.io.File ; 30 import java.io.IOException ; 31 import java.net.URL ; 32 import java.rmi.RemoteException ; 33 import java.util.ArrayList ; 34 import java.util.Enumeration ; 35 import java.util.HashSet ; 36 import java.util.List ; 37 import java.util.Set ; 38 import java.util.StringTokenizer ; 39 import java.util.Vector ; 40 41 import javax.management.InstanceAlreadyExistsException ; 42 import javax.management.InstanceNotFoundException ; 43 import javax.management.MBeanRegistrationException ; 44 import javax.management.MBeanServer ; 45 import javax.naming.Context ; 46 import javax.naming.NamingException ; 47 import javax.resource.spi.XATerminator ; 48 import javax.resource.spi.work.WorkManager ; 49 50 import org.objectweb.transaction.jta.TransactionManager; 51 52 import org.objectweb.jonas_lib.JWorkManager; 53 import org.objectweb.jonas_rar.deployment.lib.wrapper.RarManagerWrapper; 54 55 import org.objectweb.jonas.common.JModule; 56 import org.objectweb.jonas.common.JProp; 57 import org.objectweb.jonas.common.Log; 58 import org.objectweb.jonas.container.EJBService; 59 import org.objectweb.jonas.jmx.JmxService; 60 import org.objectweb.jonas.jmx.JonasObjectName; 61 import org.objectweb.jonas.jtm.TransactionService; 62 import org.objectweb.jonas.naming.CompNamingContext; 63 import org.objectweb.jonas.server.LoaderManager; 64 import org.objectweb.jonas.service.AbsServiceImpl; 65 import org.objectweb.jonas.service.ServiceException; 66 import org.objectweb.jonas.service.ServiceManager; 67 68 import org.objectweb.util.monolog.api.BasicLevel; 69 import org.objectweb.util.monolog.api.Logger; 70 71 81 public class ResourceServiceImpl extends AbsServiceImpl implements 82 ResourceService, 83 ResourceServiceImplMBean { 84 85 89 private static Logger logger = null; 90 93 private static Logger poolLogger = null; 94 97 private static Logger setterLogger = null; 98 101 private static Logger manageLogger = null; 102 103 105 109 public static final String AUTOLOADDIR = "jonas.service.resource.autoloaddir"; 110 113 public static final String CLASS = "jonas.service.resource.class"; 114 117 public static final String JNDI_NAME = "jndiname"; 118 121 public static final String RAR_OBJNAME = "rarobjname"; 122 125 public static final String FACTORY_OFFSET = "factoryoffset"; 126 129 public static final String FACTORY_TYPE = "factorytype"; 130 133 public static final String RAR_FILENAME = "rarfilename"; 134 137 public static final String LNK_JNDI_NAME = "lnkjndiname"; 138 141 public static final String LNK_RAR_FILENAME = "lnkrarfilename"; 142 145 public static final String JONAS_RA_XML = "jonasraxml"; 146 149 public static final String RA_XML = "raxml"; 150 153 public static final String PARSINGWITHVALIDATION = "jonas.service.resource.parsingwithvalidation"; 154 157 public static final String RESOURCE_LIST = "jonas.service.resource.resources"; 158 161 public static final String THREADWAITTIMEOUT = "jonas.service.resource.threadwaittimeout"; 162 165 public static final String MINWORKTHREADS = "jonas.service.resource.minworkthreads"; 166 169 public static final String MAXWORKTHREADS = "jonas.service.resource.maxworkthreads"; 170 173 public static final String EXECTIMEOUT = "jonas.service.resource.worktimeout"; 174 175 178 public static final int DEF_WRK_THREADWAITTIMEOUT = 60; 179 182 public static final int DEF_WRK_THREADS = 5; 183 186 public static final int DEF_MAX_WRK_THREADS = 80; 187 190 public static final int DEF_EXEC_TIME = 0; 191 192 195 199 203 205 210 private Vector delayedRAs = new Vector (); 211 214 private boolean processingDelayed = false; 215 216 219 private TransactionService ts = null; 220 223 private TransactionManager tm = null; 224 225 228 private MBeanServer mbeanServer = null; 229 230 233 private Vector autoNames = null; 234 237 private Vector resourceNames = null; 238 239 240 244 private WorkManager workMgr = null; 245 248 private ResourceBootstrapContext bootCtx = null; 249 250 253 public static final String JONAS_BASE = JProp.getJonasBase(); 254 255 258 public static final String WORK_RARS_DIR = JProp.getWorkDir() + File.separator + "rars"; 259 260 263 public static final String RARSDIR = JProp.getJonasBase() + File.separator + "rars"; 264 265 268 private ClassLoader appsClassLoader; 269 270 273 public ResourceServiceImpl() { 274 } 275 276 286 public void doInit(Context ctx) { 287 if (logger == null) { 288 logger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".process"); 289 } 290 if (poolLogger == null) { 291 poolLogger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".pool"); 292 } 293 if (setterLogger == null) { 294 setterLogger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".setters"); 295 } 296 if (manageLogger == null) { 297 manageLogger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".management"); 298 } 299 300 try { 301 LoaderManager lm = LoaderManager.getInstance(); 302 appsClassLoader = lm.getAppsLoader(); 303 } catch (Exception e) { 304 logger.log(BasicLevel.ERROR, "Cannot get the Applications ClassLoader from RAR Container Service: " + e); 305 throw new ServiceException("Cannot get the Applications ClassLoader from RAR Container Service", e); 306 } 307 308 resourceNames = new Vector (); 309 autoNames = new Vector (); 310 311 String dirValue = null; 313 try { 314 dirValue = (String ) ctx.lookup(AUTOLOADDIR); 315 if (logger.isLoggable(BasicLevel.DEBUG)) { 316 logger.log(BasicLevel.DEBUG, "autoloaddir= " + dirValue); 317 } 318 } catch (NamingException e) { 319 if (logger.isLoggable(BasicLevel.DEBUG)) { 320 logger.log(BasicLevel.DEBUG, "No autoloaddir value specified in context, usually for client container"); 321 } 322 } 323 if (dirValue != null) { 324 StringTokenizer st = new StringTokenizer (dirValue, ","); 325 String dirName = null; 326 while (st.hasMoreTokens()) { 327 dirName = normalizePath(st.nextToken().trim()); 328 addRars(dirName); 329 } 330 } 331 332 try { 334 String rs = (String ) ctx.lookup(RESOURCE_LIST); 335 if (logger.isLoggable(BasicLevel.DEBUG)) { 336 logger.log(BasicLevel.DEBUG, "resource list= " + rs); 337 } 338 if (rs != null) { 339 StringTokenizer st = new StringTokenizer (rs, ","); 340 String resFilename = null; 341 while (st.hasMoreTokens()) { 342 resFilename = normalizePath(st.nextToken().trim()); 343 resourceNames.add(resFilename); 344 } 345 } 346 } catch (NamingException e) { 347 logger.log(BasicLevel.ERROR, "Cannot lookup the configuration context at Resource service starting"); 348 } 349 350 try { 352 ServiceManager sm = ServiceManager.getInstance(); 353 ts = (TransactionService) sm.getTransactionService(); 354 tm = ts.getTransactionManager(); 355 } catch (Exception e) { 356 logger.log(BasicLevel.ERROR, "Cannot get the Transaction service: " + e); 357 throw new ServiceException("Cannot get the Transaction service: ", e); 358 } 359 360 try { 362 mbeanServer = 363 ((JmxService) ServiceManager.getInstance().getJmxService()).getJmxServer(); 364 } catch (Exception e) { 365 mbeanServer = null; 367 } 368 369 String parsingMode = "false"; 371 try { 372 parsingMode = (String ) ctx.lookup(PARSINGWITHVALIDATION); 373 } catch (NamingException e) { 374 if (logger.isLoggable(BasicLevel.DEBUG)) { 376 logger.log(BasicLevel.DEBUG, "No parsingwithvalidation value specified in context"); 377 } 378 } 379 if ("false".equalsIgnoreCase(parsingMode)) { 380 RarManagerWrapper.setParsingWithValidation(false); 381 if (logger.isLoggable(BasicLevel.DEBUG)) { 382 logger.log(BasicLevel.DEBUG, "XML parsing without validation"); 383 } 384 } else { 385 if (logger.isLoggable(BasicLevel.DEBUG)) { 386 logger.log(BasicLevel.DEBUG, "XML parsing with validation"); 387 } 388 } 389 390 EJBService ejbService = null; 392 try { 393 ejbService = (EJBService) ServiceManager.getInstance().getEjbService(); 394 workMgr = ejbService.getWorkManager(); 395 } catch (Exception e) { 396 workMgr = null; 398 } 399 400 int execTime = 0; 402 try { 403 String etime = (String ) ctx.lookup(EXECTIMEOUT); 404 execTime = (new Integer (etime)).intValue(); 405 } catch (NamingException e) { 406 if (logger.isLoggable(BasicLevel.DEBUG)) { 408 logger.log(BasicLevel.DEBUG, "No exectimeout value specified in context, usually for client container"); 409 } 410 } 411 412 int threadWaitTimeout = DEF_WRK_THREADWAITTIMEOUT; 414 try { 415 String tTimeout = (String ) ctx.lookup(THREADWAITTIMEOUT); 416 threadWaitTimeout = (new Integer (tTimeout)).intValue(); 417 if (threadWaitTimeout <= 0) { 418 threadWaitTimeout = DEF_WRK_THREADWAITTIMEOUT; 419 if (logger.isLoggable(BasicLevel.DEBUG)) { 420 logger.log(BasicLevel.DEBUG, "Resetting thread wait timeout to " + DEF_WRK_THREADWAITTIMEOUT); 421 } 422 } 423 } catch (Exception e) { 424 if (logger.isLoggable(BasicLevel.DEBUG)) { 426 logger.log(BasicLevel.DEBUG, "No workthread wait timeout value specified in context"); 427 } 428 } 429 430 int minWorkThreads = DEF_WRK_THREADS; 432 try { 433 String wThreads = (String ) ctx.lookup(MINWORKTHREADS); 434 minWorkThreads = (new Integer (wThreads)).intValue(); 435 if (minWorkThreads <= 0) { 436 minWorkThreads = DEF_WRK_THREADS; 437 if (logger.isLoggable(BasicLevel.DEBUG)) { 438 logger.log(BasicLevel.DEBUG, "Resetting min threads to " + DEF_WRK_THREADS); 439 } 440 } 441 } catch (Exception e) { 442 if (logger.isLoggable(BasicLevel.DEBUG)) { 444 logger.log(BasicLevel.DEBUG, "No min workthreads value specified in context"); 445 } 446 } 447 448 int maxWorkThreads = DEF_MAX_WRK_THREADS; 450 try { 451 String wThreads = (String ) ctx.lookup(MAXWORKTHREADS); 452 maxWorkThreads = (new Integer (wThreads)).intValue(); 453 } catch (Exception e) { 454 if (logger.isLoggable(BasicLevel.DEBUG)) { 456 logger.log(BasicLevel.DEBUG, "No max workthreads value specified in context"); 457 } 458 } 459 460 if (maxWorkThreads > 0 || workMgr == null) { 462 logger.log(BasicLevel.DEBUG, "Create a WorkManager for Resources"); 463 if (maxWorkThreads <= 0) { 464 maxWorkThreads = DEF_MAX_WRK_THREADS; 465 if (logger.isLoggable(BasicLevel.DEBUG)) { 466 logger.log(BasicLevel.DEBUG, "Resetting max threads to " + DEF_WRK_THREADS); 467 } 468 } 469 workMgr = new JWorkManager(minWorkThreads, maxWorkThreads, tm, threadWaitTimeout); 470 } 471 472 XATerminator xat = null; 474 try { 475 xat = ts.getCurrent().getXATerminator(); 476 } catch (Exception ex) { 477 logger.log(BasicLevel.ERROR, "Unable to get an XATerminator from the TransactionService"); 478 throw new ServiceException("Unable to get an XATerminator from the TransactionService", ex); 479 } 480 bootCtx = new ResourceBootstrapContext(workMgr, xat); 481 482 if (logger.isLoggable(BasicLevel.DEBUG)) { 483 logger.log(BasicLevel.DEBUG, "ResourceService initialized"); 484 } 485 } 486 487 491 public void doStart() throws ServiceException { 492 String rarFileName = null; 494 CompNamingContext ctx = null; 495 for (int i = 0; i < resourceNames.size(); i++) { 496 rarFileName = (String ) resourceNames.elementAt(i); 497 if (logger.isLoggable(BasicLevel.DEBUG)) { 498 logger.log(BasicLevel.DEBUG, "rarFileName=" + rarFileName); 499 } 500 try { 501 ctx = new CompNamingContext(rarFileName); 502 ctx.rebind("rarFileName", rarFileName); 503 ctx.rebind("isInEar", new Boolean (false)); 504 ctx.rebind("classloader", appsClassLoader); 505 createResourceAdapter(ctx); 506 } catch (Exception e) { 507 logger.log(BasicLevel.ERROR, "JOnAS: Cannot create resource: " + rarFileName + " exception: " + e); 508 e.printStackTrace(); 509 } 510 } 511 512 if (!delayedRAs.isEmpty()) { 514 try { 515 processingDelayed = true; 516 Object [] rList = null; 517 rList = delayedRAs.toArray(); 518 for (int i = 0; i < rList.length; i++) { 519 try { 520 createResourceAdapter((CompNamingContext) rList[i]); 521 } catch (Exception e) { 522 e.printStackTrace(); 523 String rFile = (String ) ((CompNamingContext) rList[i]).lookup("rarFileName"); 524 logger.log(BasicLevel.ERROR, "JOnAS: Cannot create resource: " + rFile + " exception: " + e); 525 logger.log(BasicLevel.ERROR, "Please verify that the rarlink is correct/deployed"); 526 } 527 } 528 } catch (Exception e) { 529 e.printStackTrace(); 530 logger.log(BasicLevel.ERROR, "ResourceService: Error with delayed RAR file deployment\n" + e); 531 throw new ServiceException("ResourceService: Error with delayed RAR file deployment", e); 532 } 533 } 534 535 if (mbeanServer != null) { 537 try { 538 mbeanServer.registerMBean(this, JonasObjectName.resourceService()); 539 } catch (InstanceAlreadyExistsException iae) { 540 logger.log(BasicLevel.ERROR, "Cannot start the Resource Service Already Exists:\n" + iae); 541 throw new ServiceException("Cannot start the Resource Service Already Exists", iae); 542 } catch (Exception e) { 543 logger.log(BasicLevel.ERROR, "ResourceService: Cannot start the Resource service:\n" + e); 544 throw new ServiceException("ResourceService: Cannot start the Resource service", e); 545 } 546 } 547 548 } 549 550 554 public void doStop() throws ServiceException { 555 556 ServiceException se = null; 557 synchronized (Rar.fileName2RA) { 558 Enumeration keys = Rar.fileName2RA.elements(); 559 while (keys.hasMoreElements()) { 560 Rar ra = (Rar) keys.nextElement(); 561 try { 562 ra.unRegister(); 563 Rar.fileName2RA.remove(ra); 564 } catch (Exception ex) { 565 logger.log(BasicLevel.ERROR, "ResourceService: Received the following:" + ex); 566 ex.printStackTrace(); 567 if (se == null) { 568 se = new ServiceException(ex.getMessage()); 569 } 570 } 571 } 572 } 573 if (mbeanServer != null) { 575 try { 576 mbeanServer.unregisterMBean(JonasObjectName.resourceService()); 578 } catch (MBeanRegistrationException mr) { 579 logger.log(BasicLevel.ERROR, "Cannot cleanly stop the ResourceService: " 580 + mr.getMessage()); 581 } catch (InstanceNotFoundException infe) { 582 logger.log(BasicLevel.ERROR, "Cannot cleanly stop the ResourceService: " 583 + infe.getMessage()); 584 } catch (Exception e) { 585 logger.log(BasicLevel.ERROR, "ResourceService: Cannot stop the Resource service:\n" + e); 586 throw new ServiceException("ResourceService: Cannot stop the Resource service", e); 587 } 588 } 589 590 if (se != null) { 591 throw se; 592 } 593 if (logger.isLoggable(BasicLevel.DEBUG)) { 594 logger.log(BasicLevel.DEBUG, "ResourceService stopped"); 595 } 596 } 597 598 599 601 608 public String createResourceAdapter(Context ctx) throws Exception { 609 610 String rarFileName; 613 try { 614 rarFileName = (String ) ctx.lookup("rarFileName"); 615 ctx.rebind("deployed", new Boolean (false)); 616 } catch (Exception ex) { 617 String err = "Error while getting parameter from context param."; 618 logger.log(BasicLevel.ERROR, err + ex.getMessage()); 619 throw new ResourceServiceException(err, ex); 620 } 621 622 if (logger.isLoggable(BasicLevel.DEBUG)) { 623 logger.log(BasicLevel.DEBUG, rarFileName); 624 } 625 if (!rarFileName.endsWith(".rar")) { 626 rarFileName += ".rar"; 627 ctx.rebind("rarFileName", rarFileName); 628 } 629 630 File f = new File (rarFileName); 632 if (!f.exists()) { 633 boolean found = false; 634 String resFileName = null; 635 resFileName = RARSDIR + File.separator + rarFileName; 638 f = new File (resFileName); 639 found = f.exists(); 640 if (found) { 641 rarFileName = resFileName; 642 ctx.rebind("rarFileName", rarFileName); 643 } else { 644 logger.log(BasicLevel.ERROR, "createResourceAdapter: " + resFileName + " not found"); 645 Exception e = new NamingException (resFileName + " not found"); 646 throw e; 647 } 648 } 649 650 URL rarUrl = f.toURL(); 651 652 Rar rar = new Rar(ctx, getDomainName(), getJonasServerName(), workMgr, bootCtx); 653 654 try { 655 Context ctxRar = rar.processRar(); 656 } catch (Exception ex) { 657 String err = "Error processing Rar: " + ex.getMessage(); 659 try { 660 rar.unRegister(); 661 } catch (Exception exc) { 662 err = err + " Unregister also failed with " + exc.getMessage(); 663 } 664 logger.log(BasicLevel.ERROR, err); 665 throw new ResourceServiceException(err, ex); 666 } 667 668 boolean isDeployed = false; 669 try { 670 isDeployed = ((Boolean ) ctx.lookup("deployed")).booleanValue(); 671 } catch (Exception ex) { 672 String err = "Error while getting parameter(isDeployed) from context param."; 673 logger.log(BasicLevel.ERROR, err + ex.getMessage()); 674 throw new ResourceServiceException(err, ex); 675 } 676 677 if (!isDeployed) { 678 if (processingDelayed) { 682 logger.log(BasicLevel.ERROR, "ResourceService.createRA: Resource (" + rarFileName + ") contains an invalid rarlink."); 683 throw new ResourceServiceException("resource input file incorrect: invalid rarlink"); 684 } 685 delayedRAs.add(ctx); 686 return null; 687 } 688 689 Vector jNames = rar.getJndinames(); 690 if (jNames != null) { 691 for (int i = 0; i < jNames.size(); i++) { 692 Rar.jndiName2RA.put(jNames.get(i), rar); 693 } 694 } 695 696 Rar.fileName2RA.put(rarUrl.getPath(), rar); 698 699 String onRar = null; 700 try { 701 onRar = (String ) ctx.lookup("onRar"); 702 } catch (Exception ex) { 703 String err = "Error while getting parameter(onRar) from context param."; 704 logger.log(BasicLevel.ERROR, err + ex.getMessage()); 705 throw new ResourceServiceException(err, ex); 706 } 707 708 return onRar.toString(); 709 } 710 711 712 726 public void deployRars(Context ctx) throws ResourceServiceException { 727 728 URL [] urls = null; 734 URL earUrl = null; 735 ClassLoader earClassLoader = null; 736 URL [] altDDs = null; 737 try { 738 urls = (URL []) ctx.lookup("urls"); 739 |