1 2 24 package com.sun.ejb.codegen; 25 26 import java.lang.reflect.*; 27 import java.net.URL ; 28 import java.net.URLConnection ; 29 import java.net.MalformedURLException ; 30 import java.io.*; 31 import java.util.*; 32 import java.util.jar.*; 33 import java.util.zip.*; 34 import java.util.logging.Logger ; 35 import java.util.logging.Level ; 36 37 import static com.sun.corba.ee.spi.codegen.Wrapper.*; 38 39 import com.sun.ejb.codegen.*; 40 import com.sun.ejb.EJBUtils; 41 import com.sun.enterprise.deployment.*; 42 import com.sun.enterprise.deployment.backend.DeploymentMode; 43 import com.sun.enterprise.deployment.backend.WebServiceDeployer; 44 import com.sun.enterprise.deployment.deploy.shared.FileArchive; 45 import com.sun.enterprise.deployment.runtime.IASEjbExtraDescriptors; 46 import com.sun.enterprise.log.Log; 47 import com.sun.enterprise.util.*; 48 import com.sun.enterprise.util.i18n.StringManager; 49 import com.sun.enterprise.util.zip.ZipFileException; 50 import com.sun.enterprise.util.zip.ZipItem; 51 import com.sun.enterprise.webservice.codegen.JaxRpcCodegenAdapter; 52 import com.sun.enterprise.webservice.codegen.JaxRpcCodegenFactory; 53 import com.sun.logging.LogDomains; 54 55 65 public final class IASEJBC { 66 67 private static final StringManager localStrings = 68 StringManager.getManager(IASEJBC.class); 69 private static final Logger _logger = 70 LogDomains.getLogger(LogDomains.DPL_LOGGER); 71 72 75 private IASEJBC() { } 76 77 85 private String getFileName(String className, String repository) { 86 87 return (repository + File.separator 88 + className.replace('.', File.separatorChar) + ".java"); 89 } 90 91 99 private String getClassName(String fileName, String repository) { 100 101 String className = fileName; 102 if (className.startsWith(repository)) 103 className = className.substring(repository.length()); 104 105 if (className.indexOf(".java") != -1) 106 className = className.substring(0, className.indexOf(".java")); 107 else if (className.indexOf(".class") != -1) 108 className = className.substring(0, className.indexOf(".class")); 109 110 className = className.replace(File.separatorChar, '.'); 111 if (className.charAt(0) == '.') 112 className = className.substring(1); 113 114 return className; 115 } 116 117 126 private OutputStream createOutputStream(String fileName) 127 throws IOException 128 { 129 File file = new File(fileName); 130 File parent = null; 131 132 if ( (parent=file.getParentFile()) != null) 133 { 134 if ( !parent.exists() ) 135 { 136 parent.mkdirs(); 137 } 138 } 139 140 FileOutputStream out = new FileOutputStream(fileName); 141 BufferedOutputStream bout = new BufferedOutputStream(out); 142 143 return bout; 144 } 145 146 147 157 private String generateCode(Generator gen, Vector files, File rep) 158 throws Exception 159 { 160 161 String genClass = gen.getGeneratedClass(); 162 String repository = rep.getCanonicalPath(); 163 String genFile = getFileName(genClass, repository); 164 165 OutputStream out = createOutputStream(genFile); 166 PrintStream ps = new PrintStream(out); 167 ((ClassGeneratorFactory)gen).evaluate(); 168 _sourceCode(ps, null); 169 out.close(); 170 171 _logger.log(Level.FINE, 172 "[EJBC] Adding to generated files: " + genFile); 173 174 files.addElement(genFile); 175 176 return genFile; 177 } 178 179 192 private void compileAndRmic(String classPath, List rmicOptions, 193 Set stubClasses, File destDir, 194 String repository) 195 throws GeneratorException, IOException 196 { 197 198 if( (stubClasses.size() == 0) ) { 199 _logger.log(Level.FINE, "[EJBC] No code generation required"); 200 return; 201 } 202 203 progress(localStrings.getStringWithDefault( 204 "generator.compiling_rmi_iiop", 205 "Compiling RMI-IIOP code.")); 206 207 List options = new ArrayList(); 208 List fileList = new ArrayList(); 209 210 options.addAll(rmicOptions); 211 212 options.add("-classpath"); 213 String bigClasspath = System.getProperty("java.class.path") 214 + File.pathSeparator + classPath 215 + File.pathSeparator + repository; 216 217 options.add(bigClasspath); 218 options.add("-d"); 219 options.add(destDir.toString()); 220 221 for(Iterator extraIter = stubClasses.iterator(); 222 extraIter.hasNext();) { 223 String next = (String ) extraIter.next(); 224 _logger.log(Level.FINE,"[EJBC] rmic " + next + "..."); 225 fileList.add(next); 226 } 227 228 try { 229 RMICompiler rmic = new RMICompiler(options, fileList); 230 rmic.setClasspath(bigClasspath); 231 rmic.compile(); 232 233 } catch(JavaCompilerException e) { 234 _logger.log(Level.FINE,"ejbc.codegen_rmi_fail",e); 235 String msg = 236 localStrings.getString("generator.rmic_compilation_failed"); 237 GeneratorException ge = new GeneratorException(msg); 238 ge.initCause(e); 239 throw ge; 240 } 241 242 if (_logger.isLoggable(Level.FINE)){ 243 StringBuffer sbuf = new StringBuffer (); 244 for(Iterator it = options.iterator(); it.hasNext(); ) { 245 sbuf.append("\n\t").append(it.next()); 246 } 247 for(Iterator it = fileList.iterator(); it.hasNext(); ) { 248 sbuf.append("\n\t").append(it.next()); 249 } 250 _logger.log(Level.FINE,"[EJBC] RMIC COMMAND: " + sbuf.toString()); 251 } 252 return; 253 } 254 255 266 public static void compileClasses(String classPath, Vector files, 267 File destDir, String repository, List javacOptions) 268 throws GeneratorException { 269 270 List options = new ArrayList(); 271 List fileList = new ArrayList(); 272 273 if (files.size() <= 0) { 274 return; 275 } 276 277 279 options.addAll(javacOptions); 280 options.add("-d"); 281 options.add(destDir.toString()); 282 options.add("-classpath"); 283 options.add(System.getProperty("java.class.path") 284 + File.pathSeparator + classPath 285 + File.pathSeparator + repository); 286 287 fileList.addAll(files); 288 289 for(Iterator it = fileList.iterator(); it.hasNext(); ) 290 { 291 String file = (String )it.next(); 292 _logger.log(Level.FINE,localStrings.getStringWithDefault( 293 "generator.compile", 294 "Compiling {0} ...", new Object [] {file} )); 295 } 296 297 if (_logger.isLoggable(Level.FINE)) { 298 StringBuffer sbuf = new StringBuffer (); 299 for ( Iterator it = options.iterator(); it.hasNext(); ) { 300 sbuf.append("\n\t").append((String )it.next()); 301 } 302 _logger.log(Level.FINE,"[EJBC] JAVAC COMMAND: " + sbuf.toString()); 303 } 304 305 long start = System.currentTimeMillis(); 306 long end = start; 307 308 try { 309 JavaCompiler jc = new JavaCompiler(options, fileList); 310 jc.compile(); 311 } catch(JavaCompilerException jce) { 312 _logger.log(Level.FINE,"ejbc.codegen_compile_failed", jce); 313 String msg = 314 localStrings.getStringWithDefault( 315 "generator.java_complilation_failed", 316 "Compilation failed: {0}", 317 new Object [] {jce.getMessage()} ); 318 GeneratorException ge = new GeneratorException(msg); 319 ge.initCause(jce); 320 throw ge; 321 } 322 323 end = System.currentTimeMillis(); 324 _logger.log(Level.FINE,"JAVA compile time (" + fileList.size() 325 + " files) = " + (end - start)); 326 } 327 328 335 private void addGeneratedFiles(Set stubClasses, 336 Vector allClientFiles, File stubsDir) 337 { 338 for (Iterator iter = stubClasses.iterator(); iter.hasNext();) { 339 String next = (String ) iter.next(); 340 String stubFile = stubsDir.toString() + File.separator + 341 GeneratedNames.getStubName(next).replace('.', 342 File.separatorChar) + ".class"; 343 allClientFiles.add(stubFile); 344 } 345 346 _logger.log(Level.FINE, 347 "[EJBC] Generated client files: " + allClientFiles); 348 } 349 350 358 private ZipItem[] getClientZipEntries(Vector allClientFiles, 359 File stubsDir) 360 throws IOException, ZipFileException { 361 362 final int CLIENT_SZ = allClientFiles.size(); 364 365 ZipItem[] zipEntries = new ZipItem[CLIENT_SZ]; 366 367 String stubsDirPath = stubsDir.toString(); 371 372 for (int i=0; i<CLIENT_SZ; i++) { 373 String longName = (String ) allClientFiles.elementAt(i); 374 File file = new File(longName); 375 376 _logger.log(Level.FINE,"[EJBC] stubs - >>"+longName); 377 378 String entryName = ""; 380 if (longName.startsWith(stubsDirPath)) { 381 entryName = longName.substring(stubsDirPath.length()); 382 if (entryName.charAt(0) == File.separatorChar) { 383 entryName = entryName.substring(1); 384 } 385 } else { 386 String msg = 388 localStrings.getString("generator.unknown_class_prefix"); 389 throw new RuntimeException (msg); 390 } 391 entryName = entryName.replace(File.separatorChar,'/'); 393 394 zipEntries[i] = new ZipItem(file, entryName); 396 } 397 398 return zipEntries; 400 } 401 402 private Set getRemoteSuperInterfaces(ClassLoader jcl, 403 String homeRemoteIntf) 404 throws ClassNotFoundException { 405 406 Set allSuperInterfaces = 409 TypeUtil.getSuperInterfaces(jcl, homeRemoteIntf,"java.rmi.Remote"); 410 411 Set remoteSuperInterfaces = new HashSet(); 412 413 Iterator iter = allSuperInterfaces.iterator(); 414 while (iter.hasNext()) { 415 String intfName = (String ) iter.next(); 416 Class intfClass = jcl.loadClass(intfName); 417 if ( java.rmi.Remote .class.isAssignableFrom(intfClass) && 418 !(intfName.equals("javax.ejb.EJBHome")) && 419 !(intfName.equals("javax.ejb.EJBObject")) ) { 420 remoteSuperInterfaces.add(intfName); 421 } 422 } 423 424 return remoteSuperInterfaces; 425 } 426 427 442 private Set getEjbClientStubClasses(ClassLoader jcl, 443 Application application, Set stubClasses) 444 throws IOException, ClassNotFoundException 445 { 446 447 Set ejbClientStubClasses = new HashSet(); 448 final String BASE_HOME = "javax.ejb.EJBHome"; 449 final String BASE_REMOTE = "javax.ejb.EJBObject"; 450 451 Vector ejbRefs = application.getEjbReferenceDescriptors(); 452 453 for (int i = 0; i < ejbRefs.size(); i++) { 454 455 EjbReferenceDescriptor next = 456 (EjbReferenceDescriptor) ejbRefs.get(i); 457 458 if( next.isLocal() || next.isEJB30ClientView() ) { 459 continue; 460 } 461 462 String home = next.getEjbHomeInterface(); 463 String remote = next.getEjbInterface(); 464 465 ejbClientStubClasses.add(home); 466 Set homeSuperIntfs = getRemoteSuperInterfaces(jcl, home); 467 ejbClientStubClasses.addAll(homeSuperIntfs); 468 469 ejbClientStubClasses.add(remote); 470 Set remoteSuperIntfs = getRemoteSuperInterfaces(jcl, remote); 471 ejbClientStubClasses.addAll(remoteSuperIntfs); 472 } 473 474 return ejbClientStubClasses; 475 } 476 477 489 private Set getStubClasses(ClassLoader jcl, 490 Set ejbHomeInterfaces, Set ejbRemoteInterfaces, 491 List remoteEjbDescriptors) 492 throws IOException, ClassNotFoundException 493 { 494 495 Set stubClasses = new HashSet(); 496 497 for (Iterator iter = remoteEjbDescriptors.iterator(); iter.hasNext();) 498 { 499 500 EjbDescriptor desc = (EjbDescriptor) iter.next(); 501 502 String home = desc.getHomeClassName(); 503 String remote = desc.getRemoteClassName(); 504 505 stubClasses.add(home); 506 Set homeSuperIntfs = getRemoteSuperInterfaces(jcl, home); 507 stubClasses.addAll(homeSuperIntfs); 508 509 510 stubClasses.add(remote); 511 Set remoteSuperIntfs = getRemoteSuperInterfaces(jcl, remote); 512 stubClasses.addAll(remoteSuperIntfs); 513 514 } 515 516 return stubClasses; 517 } 518 519 527 private String getClassPath(String [] paths, File other) { 528 529 StringBuffer sb = new StringBuffer (); 530 531 for (int i=0; i<paths.length; i++) { 532 sb.append(paths[i]+File.pathSeparator); 533 } 534 535 if (other != null) { 536 sb.append(other.toString()); 537 } 538 539 return sb.toString(); 540 } 541 542 575 public static ZipItem[] ejbc(EjbcContext ejbcCtx) 576 throws GeneratorException, ClassNotFoundException , IOException, 577 CmpCompilerException, Exception 578 { 579 IASEJBC ejbc = new IASEJBC(); 580 return ejbc.doCompile(ejbcCtx); 581 } 582 583 private ZipItem[] doCompile(EjbcContext ejbcCtx) 584 throws GeneratorException, ClassNotFoundException , IOException, 585 CmpCompilerException, Exception 586 { 587 588 File stubsDir = ejbcCtx.getStubsDir(); 590 591 Application application = ejbcCtx.getDescriptor(); 593 594 long startTime = now(); 595 long time; 597 _logger.log(Level.FINE, "ejbc.begin",application.getRegistrationName()); 598 599 String classPath = getClassPath(ejbcCtx.getClasspathUrls(), stubsDir); 601 602 final ClassLoader jcl = application.getClassLoader(); 605 606 if (!stubsDir.exists()) { 608 stubsDir.mkdirs(); 609 } 610 final String gnrtrTMP = stubsDir.getCanonicalPath(); 612 613 final ClassLoader oContextCL = 615 Thread.currentThread().getContextClassLoader(); 616 617 java.security.AccessController.doPrivileged( 619 new java.security.PrivilegedAction () { 620 public Object run() { 621 Thread.currentThread().setContextClassLoader(jcl); 622 return null; 623 } 624 } 625 ); 626 627 628 630 if (application.containsCMPEntity()) { 631 CmpCompiler cmpc = new CmpCompiler(ejbcCtx); 632 cmpc.compile(); 633 } 634 635 637 639 Vector ejbRemoteDeploymentDescriptors = new Vector(); 640 Set ejbHomeInterfaces = new HashSet(); 641 Set ejbRemoteInterfaces = new HashSet(); 642 Set<String > nonSerializableSfulClasses = new HashSet(); 643 Set<String > ejb30RemoteBusinessInterfaces = new HashSet(); 644 645 int ejbCount = 0; 650 Iterator iter = application.getEjbDescriptors().iterator(); 651 652 653 boolean generateRmicStubs = 668 ( ejbcCtx.getDeploymentRequest().getGenerateRMIStubs() ); 669 672 while (iter.hasNext()) { 673 ejbCount++; 674 EjbDescriptor next = (EjbDescriptor) iter.next(); 675 676 677 if( next.isLocalBusinessInterfacesSupported() ) { 678 for(String nextBusIntfStr : 679 next.getLocalBusinessClassNames() ) { 680 Class intf = jcl.loadClass(nextBusIntfStr); 681 if(javax.ejb.EJBLocalObject .class.isAssignableFrom(intf)) { 682 throw new GeneratorException("Invalid Local Business " 683 + "Interface " + intf + ". A Local Business " + 684 "interface MUST not extend javax.ejb.EJBLocalObject"); 685 } 686 } 687 } 688 689 if( next.isRemoteInterfacesSupported() ) { 690 691 if( generateRmicStubs ) { 692 ejbRemoteDeploymentDescriptors.addElement(next); 693 ejbHomeInterfaces.add(next.getHomeClassName()); 694 ejbRemoteInterfaces.add(next.getRemoteClassName()); 695 } else { 696 _logger.log(Level.FINE, 697 "Skipping RMI-IIOP STUB generation for" 698 + " " + next.getName()); 699 } 700 } 701 702 if( next.isRemoteBusinessInterfacesSupported() ) { 703 704 for(String nextIntf : next.getRemoteBusinessClassNames() ) { 705 if( !ejb30RemoteBusinessInterfaces.contains(nextIntf) ) { 712 ejb30RemoteBusinessInterfaces.add(nextIntf); 713 } 714 } 715 } 716 717 if( next.getType().equals(EjbSessionDescriptor.TYPE) && 718 ((EjbSessionDescriptor)next).isStateful() ) { 719 720 Set<String > classNames = new HashSet<String >(); 721 classNames.add(next.getEjbClassName()); 722 classNames.addAll(next.getInterceptorClassNames()); 723 724 for(String className : classNames) { 725 Class clazz = jcl.loadClass(className); 726 if( !Serializable.class.isAssignableFrom(clazz) ) { 727 nonSerializableSfulClasses.add(className); 730 } 731 } 732 } 733 } 734 735 Vector ejbRefs = application.getEjbReferenceDescriptors(); 739 for (int i = 0; i < ejbRefs.size(); i++) { 740 EjbReferenceDescriptor next = 741 (EjbReferenceDescriptor) ejbRefs.get(i); 742 if( next.isEJB30ClientView() && !next.isLocal() ) { 743 String busInterface = next.getEjbInterface(); 744 if( !ejb30RemoteBusinessInterfaces.contains(busInterface) ) { 745 ejb30RemoteBusinessInterfaces.add(busInterface); 746 } 747 } 748 } 749 750 progress(localStrings.getStringWithDefault 751 ("generator.processing_beans", "Processing beans...")); 752 753 754 756 758 FileArchive dArchive = new FileArchive(); 759 dArchive.open(gnrtrTMP); 760 DeploymentContext context = new DeploymentContext(dArchive,application); 761 762 Vector remote30Files = new Vector(); 764 765 if( EJBUtils.useStaticCodegen() ) { 766 767 Generator genericHomeGen = new GenericHomeGenerator 769 (context.getClassLoader()); 770 771 generateCode(genericHomeGen, remote30Files, stubsDir); 772 773 for (String businessIntf : ejb30RemoteBusinessInterfaces) { 774 775 Generator remoteGen = 777 new RemoteGenerator(context.getClassLoader(), 778 businessIntf); 779 780 generateCode(remoteGen, remote30Files, stubsDir); 781 782 Generator clientGen = new Remote30WrapperGenerator 783 (context.getClassLoader(), businessIntf, 784 remoteGen.getGeneratedClass()); 785 786 generateCode(clientGen, remote30Files, stubsDir); 787 } 788 if (remote30Files.size() > 0) { 790 791 time = now(); 793 compileClasses(classPath, remote30Files, stubsDir, gnrtrTMP, 794 ejbcCtx.getJavacOptions()); 795 ejbcCtx.getTiming().javaCompileTime += (now() - time); 796 797 _logger.fine("Done generating Remote business intfs"); 798 } 799 800 801 Vector serializableSfulSubClasses = new Vector(); 806 for(String className : nonSerializableSfulClasses) { 807 Generator serializableSfulGen = 808 new SerializableBeanGenerator(context.getClassLoader(), 809 className); 810 811 generateCode(serializableSfulGen, serializableSfulSubClasses, 812 stubsDir); 813 } 814 815 if( serializableSfulSubClasses.size() > 0 ) { 816 time = now(); 818 compileClasses(classPath, serializableSfulSubClasses, stubsDir, 819 gnrtrTMP, ejbcCtx.getJavacOptions()); 820 821 ejbcCtx.getTiming().javaCompileTime += (now() - time); 822 823 _logger.fine("Generated Stateful Serializable subclasses"); 824 825 } 826 } 827 828 830 831 if (_logger.isLoggable(Level.FINE)) { 832 _logger.log(Level.FINE, "ejbc.start_jaxrpc_generation", 833 application.getRegistrationName()); 834 } 835 time = now(); 836 837 JaxRpcCodegenFactory jaxrpcFactory = 838 JaxRpcCodegenFactory.newInstance(); 839 JaxRpcCodegenAdapter jaxrpcAdapter = jaxrpcFactory.getAdapter(); 840 jaxrpcAdapter.run(ejbcCtx); 841 842 ejbcCtx.getTiming().jaxrpcGenerationTime += (now() - time); 843 844 if (_logger.isLoggable(Level.FINE)) { 845 _logger.log(Level.FINE, "ejbc.end_jaxrpc_generation", 846 application.getRegistrationName()); 847 } 848 849 WebServiceDeployer deployer = 854 new WebServiceDeployer(ejbcCtx.getDeploymentRequest()); 855 deployer.doWebServiceDeployment(ejbcCtx.getDescriptor(), 856 ejbcCtx.getSrcDir()); 857 858 859 861 863 Set allStubClasses = new HashSet(); 864 865 if( generateRmicStubs ) { 866 Set ejbStubClasses = getStubClasses(jcl, ejbHomeInterfaces, 868 ejbRemoteInterfaces, ejbRemoteDeploymentDescriptors); 869 870 Set ejbClientStubClasses = 874 getEjbClientStubClasses(jcl, application, ejbStubClasses); 875 876 allStubClasses.addAll(ejbStubClasses); 877 allStubClasses.addAll(ejbClientStubClasses); 878 879 881 time = now(); 882 compileAndRmic(classPath, ejbcCtx.getRmicOptions(), allStubClasses, 883 stubsDir, gnrtrTMP); 884 885 ejbcCtx.getTiming().RMICompileTime += (now() - time); 886 } 887 888 890 Vector allClientFiles = new Vector(); 892 893 addGeneratedFiles(allStubClasses, allClientFiles, stubsDir); 895 896 if( remote30Files.size() > 0 ) { 897 898 Iterator itr = remote30Files.iterator(); 899 if (itr != null) { 900 for (;itr.hasNext();) { 901 String file = (String ) itr.next(); 902 allClientFiles.add(file.replace(".java", ".class")); 903 } 904 } 905 906 } 907 908 if (jaxrpcAdapter!=null) { 909 Iterator itr = jaxrpcAdapter.getListOfBinaryFiles(); 910 if (itr!=null) { 911 for (;itr.hasNext();) { 912 allClientFiles.add(itr.next()); 913 } 914 } 915 } 916 917 ZipItem[] clientStubs = getClientZipEntries(allClientFiles, stubsDir); 919 920 _logger.log(Level.FINE, "ejbc.end", application.getRegistrationName()); 921 ejbcCtx.getTiming().totalTime = now() - startTime; 922 923 java.security.AccessController.doPrivileged( 926 new java.security.PrivilegedAction () { 927 public Object run() { 928 Thread.currentThread().setContextClassLoader(oContextCL); 929 return null; 930 } 931 } 932 ); 933 934 937 jaxrpcAdapter.done(); 938 939 return clientStubs; 940 } 941 942 private long now() 943 { 944 return System.currentTimeMillis(); 945 } 946 947 private void progress(String message) { 948 try { 949 _logger.log(Level.FINE, message); 950 } catch(Throwable t) { 951 _logger.log(Level.FINER,"Cannot set status message",t); 952 } 953 } 954 955 } 956 | Popular Tags |