source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 30.9 KB
Line 
1/*
2 * Copyright 2001-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.tools.ant.taskdefs.optional.ejb;
18
19import java.io.File;
20import java.io.FileOutputStream;
21import java.io.IOException;
22import java.io.InputStream;
23import java.util.Enumeration;
24import java.util.Hashtable;
25import java.util.Iterator;
26import java.util.jar.JarEntry;
27import java.util.jar.JarFile;
28import java.util.jar.JarOutputStream;
29import org.apache.tools.ant.BuildException;
30import org.apache.tools.ant.Project;
31import org.apache.tools.ant.taskdefs.Java;
32import org.apache.tools.ant.types.EnumeratedAttribute;
33import org.apache.tools.ant.types.Environment;
34import org.apache.tools.ant.types.Path;
35import org.apache.tools.ant.util.FileUtils;
36
37/**
38 * Websphere deployment tool that augments the ejbjar task.
39 * Searches for the websphere specific deployment descriptors and
40 * adds them to the final ejb jar file. Websphere has two specific descriptors for session
41 * beans:
42 * <ul>
43 * <li>ibm-ejb-jar-bnd.xmi</li>
44 * <li>ibm-ejb-jar-ext.xmi</li>
45 * </ul>
46 * and another two for container managed entity beans:
47 * <ul>
48 * <li>Map.mapxmi</li>
49 * <li>Schema.dbxmi</li>
50 * </ul>
51 * In terms of WebSphere, the generation of container code and stubs is
52 * called <code>deployment</code>. This step can be performed by the websphere
53 * element as part of the jar generation process. If the switch
54 * <code>ejbdeploy</code> is on, the ejbdeploy tool from the websphere toolset
55 * is called for every ejb-jar. Unfortunately, this step only works, if you
56 * use the ibm jdk. Otherwise, the rmic (called by ejbdeploy) throws a
57 * ClassFormatError. Be sure to switch ejbdeploy off, if run ant with
58 * sun jdk.
59 *
60 */
61public class WebsphereDeploymentTool extends GenericDeploymentTool {
62 /**
63 * Enumerated attribute with the values for the database vendor types
64 *
65 */
66 public static class DBVendor extends EnumeratedAttribute {
67 public String[] getValues() {
68 return new String[]{
69 "SQL92", "SQL99", "DB2UDBWIN_V71", "DB2UDBOS390_V6", "DB2UDBAS400_V4R5",
70 "ORACLE_V8", "INFORMIX_V92", "SYBASE_V1192", "MSSQLSERVER_V7", "MYSQL_V323"
71 };
72 }
73 }
74
75
76 public static final String PUBLICID_EJB11
77 = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
78 public static final String PUBLICID_EJB20
79 = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN";
80 protected static final String SCHEMA_DIR = "Schema/";
81
82 protected static final String WAS_EXT = "ibm-ejb-jar-ext.xmi";
83 protected static final String WAS_BND = "ibm-ejb-jar-bnd.xmi";
84 protected static final String WAS_CMP_MAP = "Map.mapxmi";
85 protected static final String WAS_CMP_SCHEMA = "Schema.dbxmi";
86
87 /** Instance variable that stores the suffix for the websphere jarfile. */
88 private String jarSuffix = ".jar";
89
90 /** Instance variable that stores the location of the ejb 1.1 DTD file. */
91 private String ejb11DTD;
92
93 /** Instance variable that determines whether generic ejb jars are kept. */
94
95 private boolean keepGeneric = false;
96
97 private boolean alwaysRebuild = true;
98
99 private boolean ejbdeploy = true;
100
101 /** Indicates if the old CMP location convention is to be used. */
102 private boolean newCMP = false;
103
104 /** The classpath to the websphere classes. */
105 private Path wasClasspath = null;
106
107 /** The DB Vendor name, the EJB is persisted against */
108 private String dbVendor;
109
110 /** The name of the database to create. (For top-down mapping only) */
111 private String dbName;
112
113 /** The name of the schema to create. (For top-down mappings only) */
114 private String dbSchema;
115
116 /** true - Only generate the deployment code, do not run RMIC or Javac */
117 private boolean codegen;
118
119 /** true - Only output error messages, suppress informational messages */
120 private boolean quiet = true;
121
122 /** true - Disable the validation steps */
123 private boolean novalidate;
124
125 /** true - Disable warning and informational messages */
126 private boolean nowarn;
127
128 /** true - Disable informational messages */
129 private boolean noinform;
130
131 /** true - Enable internal tracing */
132 private boolean trace;
133
134 /** Additional options for RMIC */
135 private String rmicOptions;
136
137 /** true- Use the WebSphere 3.5 compatible mapping rules */
138 private boolean use35MappingRules;
139
140 /** the scratchdir for the ejbdeploy operation */
141 private String tempdir = "_ejbdeploy_temp";
142
143 /** the home directory for websphere */
144 private File websphereHome;
145
146 /** Get the classpath to the websphere classpaths */
147 public Path createWASClasspath() {
148 if (wasClasspath == null) {
149 wasClasspath = new Path(getTask().getProject());
150 }
151 return wasClasspath.createPath();
152 }
153
154
155 public void setWASClasspath(Path wasClasspath) {
156 this.wasClasspath = wasClasspath;
157 }
158
159
160 /** Sets the DB Vendor for the Entity Bean mapping ; optional.
161 * Valid options are for example:
162 * <ul>
163 * <li>SQL92</li> <li>SQL99</li> <li>DB2UDBWIN_V71</li>
164 * <li>DB2UDBOS390_V6</li> <li>DB2UDBAS400_V4R5</li> <li>ORACLE_V8</li>
165 * <li>INFORMIX_V92</li> <li>SYBASE_V1192</li> <li>MYSQL_V323</li>
166 * </ul>
167 * This is also used to determine the name of the Map.mapxmi and
168 * Schema.dbxmi files, for example Account-DB2UDBWIN_V71-Map.mapxmi
169 * and Account-DB2UDBWIN_V71-Schema.dbxmi.
170 */
171 public void setDbvendor(DBVendor dbvendor) {
172 this.dbVendor = dbvendor.getValue();
173 }
174
175
176 /**
177 * Sets the name of the Database to create; optional.
178 *
179 * @param dbName name of the database
180 */
181 public void setDbname(String dbName) {
182 this.dbName = dbName;
183 }
184
185
186 /**
187 * Sets the name of the schema to create; optional.
188 *
189 * @param dbSchema name of the schema
190 */
191 public void setDbschema(String dbSchema) {
192 this.dbSchema = dbSchema;
193 }
194
195
196 /**
197 * Flag, default false, to only generate the deployment
198 * code, do not run RMIC or Javac
199 *
200 * @param codegen option
201 */
202 public void setCodegen(boolean codegen) {
203 this.codegen = codegen;
204 }
205
206
207 /**
208 * Flag, default true, to only output error messages.
209 *
210 * @param quiet option
211 */
212 public void setQuiet(boolean quiet) {
213 this.quiet = quiet;
214 }
215
216
217 /**
218 * Flag to disable the validation steps; optional, default false.
219 *
220 * @param novalidate option
221 */
222 public void setNovalidate(boolean novalidate) {
223 this.novalidate = novalidate;
224 }
225
226
227 /**
228 * Flag to disable warning and informational messages; optional, default false.
229 *
230 * @param nowarn option
231 */
232 public void setNowarn(boolean nowarn) {
233 this.nowarn = nowarn;
234 }
235
236
237 /**
238 * Flag to disable informational messages; optional, default false.
239 *
240 * @param noinform if true disables informational messages
241 */
242 public void setNoinform(boolean noinform) {
243 this.noinform = noinform;
244 }
245
246
247 /**
248 * Flag to enable internal tracing when set, optional, default false.
249 *
250 * @param trace
251 */
252 public void setTrace(boolean trace) {
253 this.trace = trace;
254 }
255
256 /**
257 * Set the rmic options.
258 *
259 * @param options
260 */
261 public void setRmicoptions(String options) {
262 this.rmicOptions = options;
263 }
264
265 /**
266 * Flag to use the WebSphere 3.5 compatible mapping rules ; optional, default false.
267 *
268 * @param attr
269 */
270 public void setUse35(boolean attr) {
271 use35MappingRules = attr;
272 }
273
274
275 /**
276 * Set the rebuild flag to false to only update changes in the jar rather
277 * than rerunning ejbdeploy; optional, default true.
278 */
279 public void setRebuild(boolean rebuild) {
280 this.alwaysRebuild = rebuild;
281 }
282
283
284 /**
285 * String value appended to the basename of the deployment
286 * descriptor to create the filename of the WebLogic EJB
287 * jar file. Optional, default '.jar'.
288 * @param inString the string to use as the suffix.
289 */
290 public void setSuffix(String inString) {
291 this.jarSuffix = inString;
292 }
293
294
295 /**
296 * This controls whether the generic file used as input to
297 * ejbdeploy is retained; optional, default false.
298 * @param inValue either 'true' or 'false'.
299 */
300 public void setKeepgeneric(boolean inValue) {
301 this.keepGeneric = inValue;
302 }
303
304
305 /**
306 * Decide, wether ejbdeploy should be called or not;
307 * optional, default true.
308 *
309 * @param ejbdeploy
310 */
311 public void setEjbdeploy(boolean ejbdeploy) {
312 this.ejbdeploy = ejbdeploy;
313 }
314
315
316 /**
317 * Setter used to store the location of the Sun's Generic EJB DTD. This
318 * can be a file on the system or a resource on the classpath.
319 *
320 * @param inString the string to use as the DTD location.
321 */
322 public void setEJBdtd(String inString) {
323 this.ejb11DTD = inString;
324 }
325
326
327 /**
328 * Set the value of the oldCMP scheme. This is an antonym for newCMP
329 * @ant.attribute ignore="true"
330 */
331 public void setOldCMP(boolean oldCMP) {
332 this.newCMP = !oldCMP;
333 }
334
335
336 /**
337 * Set the value of the newCMP scheme. The old CMP scheme locates the
338 * websphere CMP descriptor based on the naming convention where the
339 * websphere CMP file is expected to be named with the bean name as the
340 * prefix. Under this scheme the name of the CMP descriptor does not match
341 * the name actually used in the main websphere EJB descriptor. Also,
342 * descriptors which contain multiple CMP references could not be used.
343 */
344 public void setNewCMP(boolean newCMP) {
345 this.newCMP = newCMP;
346 }
347
348
349 /**
350 * The directory, where ejbdeploy will write temporary files;
351 * optional, defaults to '_ejbdeploy_temp'.
352 */
353
354 public void setTempdir(String tempdir) {
355 this.tempdir = tempdir;
356 }
357
358
359 protected DescriptorHandler getDescriptorHandler(File srcDir) {
360 DescriptorHandler handler = new DescriptorHandler(getTask(), srcDir);
361 // register all the DTDs, both the ones that are known and
362 // any supplied by the user
363 handler.registerDTD(PUBLICID_EJB11, ejb11DTD);
364
365 for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
366 EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
367
368 handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
369 }
370
371 return handler;
372 }
373
374
375 protected DescriptorHandler getWebsphereDescriptorHandler(final File srcDir) {
376 DescriptorHandler handler =
377 new DescriptorHandler(getTask(), srcDir) {
378 protected void processElement() {
379 }
380 };
381
382 for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
383 EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
384
385 handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
386 }
387 return handler;
388 }
389
390
391 /**
392 * Add any vendor specific files which should be included in the EJB Jar.
393 */
394 protected void addVendorFiles(Hashtable ejbFiles, String baseName) {
395
396 String ddPrefix = (usingBaseJarName() ? "" : baseName);
397 String dbPrefix = (dbVendor == null) ? "" : dbVendor + "-";
398
399 // Get the Extensions document
400 File websphereEXT = new File(getConfig().descriptorDir, ddPrefix + WAS_EXT);
401
402 if (websphereEXT.exists()) {
403 ejbFiles.put(META_DIR + WAS_EXT,
404 websphereEXT);
405 } else {
406 log("Unable to locate websphere extensions. "
407 + "It was expected to be in "
408 + websphereEXT.getPath(), Project.MSG_VERBOSE);
409 }
410
411 File websphereBND = new File(getConfig().descriptorDir, ddPrefix + WAS_BND);
412
413 if (websphereBND.exists()) {
414 ejbFiles.put(META_DIR + WAS_BND,
415 websphereBND);
416 } else {
417 log("Unable to locate websphere bindings. "
418 + "It was expected to be in "
419 + websphereBND.getPath(), Project.MSG_VERBOSE);
420 }
421
422 if (!newCMP) {
423 log("The old method for locating CMP files has been DEPRECATED.",
424 Project.MSG_VERBOSE);
425 log("Please adjust your websphere descriptor and set "
426 + "newCMP=\"true\" to use the new CMP descriptor "
427 + "inclusion mechanism. ", Project.MSG_VERBOSE);
428 } else {
429 // We attempt to put in the MAP and Schema files of CMP beans
430 try {
431 // Add the Map file
432 File websphereMAP = new File(getConfig().descriptorDir,
433 ddPrefix + dbPrefix + WAS_CMP_MAP);
434
435 if (websphereMAP.exists()) {
436 ejbFiles.put(META_DIR + WAS_CMP_MAP,
437 websphereMAP);
438 } else {
439 log("Unable to locate the websphere Map: "
440 + websphereMAP.getPath(), Project.MSG_VERBOSE);
441 }
442
443 File websphereSchema = new File(getConfig().descriptorDir,
444 ddPrefix + dbPrefix + WAS_CMP_SCHEMA);
445
446 if (websphereSchema.exists()) {
447 ejbFiles.put(META_DIR + SCHEMA_DIR + WAS_CMP_SCHEMA,
448 websphereSchema);
449 } else {
450 log("Unable to locate the websphere Schema: "
451 + websphereSchema.getPath(), Project.MSG_VERBOSE);
452 }
453 // Theres nothing else to see here...keep moving sonny
454 } catch (Exception e) {
455 String msg = "Exception while adding Vendor specific files: "
456 + e.toString();
457
458 throw new BuildException(msg, e);
459 }
460 }
461 }
462
463
464 /**
465 * Get the vendor specific name of the Jar that will be output. The
466 * modification date of this jar will be checked against the dependent
467 * bean classes.
468 */
469 File getVendorOutputJarFile(String baseName) {
470 return new File(getDestDir(), baseName + jarSuffix);
471 }
472
473
474 /**
475 * Gets the options for the EJB Deploy operation
476 *
477 * @return String
478 */
479 protected String getOptions() {
480 // Set the options
481 StringBuffer options = new StringBuffer();
482
483 if (dbVendor != null) {
484 options.append(" -dbvendor ").append(dbVendor);
485 }
486 if (dbName != null) {
487 options.append(" -dbname \"").append(dbName).append("\"");
488 }
489
490 if (dbSchema != null) {
491 options.append(" -dbschema \"").append(dbSchema).append("\"");
492 }
493
494 if (codegen) {
495 options.append(" -codegen");
496 }
497
498 if (quiet) {
499 options.append(" -quiet");
500 }
501
502 if (novalidate) {
503 options.append(" -novalidate");
504 }
505
506 if (nowarn) {
507 options.append(" -nowarn");
508 }
509
510 if (noinform) {
511 options.append(" -noinform");
512 }
513
514 if (trace) {
515 options.append(" -trace");
516 }
517
518 if (use35MappingRules) {
519 options.append(" -35");
520 }
521
522 if (rmicOptions != null) {
523 options.append(" -rmic \"").append(rmicOptions).append("\"");
524 }
525
526 return options.toString();
527 }
528
529
530 /**
531 * Helper method invoked by execute() for each websphere jar to be built.
532 * Encapsulates the logic of constructing a java task for calling
533 * websphere.ejbdeploy and executing it.
534 *
535 * @param sourceJar java.io.File representing the source (EJB1.1) jarfile.
536 * @param destJar java.io.File representing the destination, websphere
537 * jarfile.
538 */
539 private void buildWebsphereJar(File sourceJar, File destJar) {
540 try {
541 if (ejbdeploy) {
542 Java javaTask = (Java) getTask().getProject().createTask("java");
543 // Set the JvmArgs
544 javaTask.createJvmarg().setValue("-Xms64m");
545 javaTask.createJvmarg().setValue("-Xmx128m");
546
547 // Set the Environment variable
548 Environment.Variable var = new Environment.Variable();
549
550 var.setKey("websphere.lib.dir");
551 File libdir = new File(websphereHome, "lib");
552 var.setValue(libdir.getAbsolutePath());
553 javaTask.addSysproperty(var);
554
555 // Set the working directory
556 javaTask.setDir(websphereHome);
557
558 // Set the Java class name
559 javaTask.setTaskName("ejbdeploy");
560 javaTask.setClassname("com.ibm.etools.ejbdeploy.EJBDeploy");
561
562 javaTask.createArg().setValue(sourceJar.getPath());
563 javaTask.createArg().setValue(tempdir);
564 javaTask.createArg().setValue(destJar.getPath());
565 javaTask.createArg().setLine(getOptions());
566 if (getCombinedClasspath() != null
567 && getCombinedClasspath().toString().length() > 0) {
568 javaTask.createArg().setValue("-cp");
569 javaTask.createArg().setValue(getCombinedClasspath().toString());
570 }
571
572 Path classpath = wasClasspath;
573
574 if (classpath == null) {
575 classpath = getCombinedClasspath();
576 }
577
578 if (classpath != null) {
579 javaTask.setClasspath(classpath);
580 javaTask.setFork(true);
581 } else {
582 javaTask.setFork(true);
583 }
584
585 log("Calling websphere.ejbdeploy for " + sourceJar.toString(),
586 Project.MSG_VERBOSE);
587
588 javaTask.execute();
589 }
590 } catch (Exception e) {
591 // Have to catch this because of the semantics of calling main()
592 String msg = "Exception while calling ejbdeploy. Details: " + e.toString();
593
594 throw new BuildException(msg, e);
595 }
596 }
597
598
599 /**
600 * Method used to encapsulate the writing of the JAR file. Iterates over
601 * the filenames/java.io.Files in the Hashtable stored on the instance
602 * variable ejbFiles.
603 */
604 protected void writeJar(String baseName, File jarFile, Hashtable files, String publicId)
605 throws BuildException {
606 if (ejbdeploy) {
607 // create the -generic.jar, if required
608 File genericJarFile = super.getVendorOutputJarFile(baseName);
609
610 super.writeJar(baseName, genericJarFile, files, publicId);
611
612 // create the output .jar, if required
613 if (alwaysRebuild || isRebuildRequired(genericJarFile, jarFile)) {
614 buildWebsphereJar(genericJarFile, jarFile);
615 }
616 if (!keepGeneric) {
617 log("deleting generic jar " + genericJarFile.toString(),
618 Project.MSG_VERBOSE);
619 genericJarFile.delete();
620 }
621 } else {
622 // create the "undeployed" output .jar, if required
623 super.writeJar(baseName, jarFile, files, publicId);
624 }
625 }
626
627
628 /**
629 * Called to validate that the tool parameters have been configured.
630 */
631 public void validateConfigured() throws BuildException {
632 super.validateConfigured();
633 if (ejbdeploy) {
634 String home = getTask().getProject().getProperty("websphere.home");
635 if (home == null) {
636 throw new BuildException("The 'websphere.home' property must "
637 + "be set when 'ejbdeploy=true'");
638 }
639 websphereHome = getTask().getProject().resolveFile(home);
640 }
641 }
642
643
644 /**
645 * Helper method to check to see if a websphere EBJ1.1 jar needs to be
646 * rebuilt using ejbdeploy. Called from writeJar it sees if the "Bean"
647 * classes are the only thing that needs to be updated and either updates
648 * the Jar with the Bean classfile or returns true, saying that the whole
649 * websphere jar needs to be regened with ejbdeploy. This allows faster
650 * build times for working developers. <p>
651 *
652 * The way websphere ejbdeploy works is it creates wrappers for the
653 * publicly defined methods as they are exposed in the remote interface.
654 * If the actual bean changes without changing the the method signatures
655 * then only the bean classfile needs to be updated and the rest of the
656 * websphere jar file can remain the same. If the Interfaces, ie. the
657 * method signatures change or if the xml deployment descriptors changed,
658 * the whole jar needs to be rebuilt with ejbdeploy. This is not strictly
659 * true for the xml files. If the JNDI name changes then the jar doesnt
660 * have to be rebuild, but if the resources references change then it
661 * does. At this point the websphere jar gets rebuilt if the xml files
662 * change at all.
663 *
664 * @param genericJarFile java.io.File The generic jar file.
665 * @param websphereJarFile java.io.File The websphere jar file to check to
666 * see if it needs to be rebuilt.
667 */
668 protected boolean isRebuildRequired(File genericJarFile, File websphereJarFile) {
669 boolean rebuild = false;
670
671 JarFile genericJar = null;
672 JarFile wasJar = null;
673 File newwasJarFile = null;
674 JarOutputStream newJarStream = null;
675
676 try {
677 log("Checking if websphere Jar needs to be rebuilt for jar "
678 + websphereJarFile.getName(), Project.MSG_VERBOSE);
679 // Only go forward if the generic and the websphere file both exist
680 if (genericJarFile.exists() && genericJarFile.isFile()
681 && websphereJarFile.exists() && websphereJarFile.isFile()) {
682 //open jar files
683 genericJar = new JarFile(genericJarFile);
684 wasJar = new JarFile(websphereJarFile);
685
686 Hashtable genericEntries = new Hashtable();
687 Hashtable wasEntries = new Hashtable();
688 Hashtable replaceEntries = new Hashtable();
689
690 //get the list of generic jar entries
691 for (Enumeration e = genericJar.entries(); e.hasMoreElements();) {
692 JarEntry je = (JarEntry) e.nextElement();
693
694 genericEntries.put(je.getName().replace('\\', '/'), je);
695 }
696 //get the list of websphere jar entries
697 for (Enumeration e = wasJar.entries(); e.hasMoreElements();) {
698 JarEntry je = (JarEntry) e.nextElement();
699
700 wasEntries.put(je.getName(), je);
701 }
702
703 //Cycle Through generic and make sure its in websphere
704 ClassLoader genericLoader = getClassLoaderFromJar(genericJarFile);
705
706 for (Enumeration e = genericEntries.keys(); e.hasMoreElements();) {
707 String filepath = (String) e.nextElement();
708
709 if (wasEntries.containsKey(filepath)) {
710 // File name/path match
711 // Check files see if same
712 JarEntry genericEntry = (JarEntry) genericEntries.get(filepath);
713 JarEntry wasEntry = (JarEntry) wasEntries.get(filepath);
714
715 if ((genericEntry.getCrc() != wasEntry.getCrc())
716 || (genericEntry.getSize() != wasEntry.getSize())) {
717
718 if (genericEntry.getName().endsWith(".class")) {
719 //File are different see if its an object or an interface
720 String classname
721 = genericEntry.getName().replace(File.separatorChar, '.');
722
723 classname = classname.substring(0, classname.lastIndexOf(".class"));
724
725 Class genclass = genericLoader.loadClass(classname);
726
727 if (genclass.isInterface()) {
728 //Interface changed rebuild jar.
729 log("Interface " + genclass.getName()
730 + " has changed", Project.MSG_VERBOSE);
731 rebuild = true;
732 break;
733 } else {
734 //Object class Changed update it.
735 replaceEntries.put(filepath, genericEntry);
736 }
737 } else {
738 // is it the manifest. If so ignore it
739 if (!genericEntry.getName().equals("META-INF/MANIFEST.MF")) {
740 //File other then class changed rebuild
741 log("Non class file " + genericEntry.getName()
742 + " has changed", Project.MSG_VERBOSE);
743 rebuild = true;
744 }
745 break;
746 }
747 }
748 } else {
749 // a file doesn't exist rebuild
750
751 log("File " + filepath + " not present in websphere jar",
752 Project.MSG_VERBOSE);
753 rebuild = true;
754 break;
755 }
756 }
757
758 if (!rebuild) {
759 log("No rebuild needed - updating jar", Project.MSG_VERBOSE);
760 newwasJarFile = new File(websphereJarFile.getAbsolutePath() + ".temp");
761 if (newwasJarFile.exists()) {
762 newwasJarFile.delete();
763 }
764
765 newJarStream = new JarOutputStream(new FileOutputStream(newwasJarFile));
766 newJarStream.setLevel(0);
767
768 //Copy files from old websphere jar
769 for (Enumeration e = wasEntries.elements(); e.hasMoreElements();) {
770 byte[] buffer = new byte[1024];
771 int bytesRead;
772 InputStream is;
773 JarEntry je = (JarEntry) e.nextElement();
774
775 if (je.getCompressedSize() == -1
776 || je.getCompressedSize() == je.getSize()) {
777 newJarStream.setLevel(0);
778 } else {
779 newJarStream.setLevel(9);
780 }
781
782 // Update with changed Bean class
783 if (replaceEntries.containsKey(je.getName())) {
784 log("Updating Bean class from generic Jar " + je.getName(),
785 Project.MSG_VERBOSE);
786 // Use the entry from the generic jar
787 je = (JarEntry) replaceEntries.get(je.getName());
788 is = genericJar.getInputStream(je);
789 } else {
790 //use fle from original websphere jar
791
792 is = wasJar.getInputStream(je);
793 }
794 newJarStream.putNextEntry(new JarEntry(je.getName()));
795
796 while ((bytesRead = is.read(buffer)) != -1) {
797 newJarStream.write(buffer, 0, bytesRead);
798 }
799 is.close();
800 }
801 } else {
802 log("websphere Jar rebuild needed due to changed "
803 + "interface or XML", Project.MSG_VERBOSE);
804 }
805 } else {
806 rebuild = true;
807 }
808 } catch (ClassNotFoundException cnfe) {
809 String cnfmsg = "ClassNotFoundException while processing ejb-jar file"
810 + ". Details: "
811 + cnfe.getMessage();
812
813 throw new BuildException(cnfmsg, cnfe);
814 } catch (IOException ioe) {
815 String msg = "IOException while processing ejb-jar file "
816 + ". Details: "
817 + ioe.getMessage();
818
819 throw new BuildException(msg, ioe);
820 } finally {
821 // need to close files and perhaps rename output
822 if (genericJar != null) {
823 try {
824 genericJar.close();
825 } catch (IOException closeException) {
826 }
827 }
828
829 if (wasJar != null) {
830 try {
831 wasJar.close();
832 } catch (IOException closeException) {
833 }
834 }
835
836 if (newJarStream != null) {
837 try {
838 newJarStream.close();
839 } catch (IOException closeException) {
840 }
841
842 try {
843 FileUtils.newFileUtils().rename(newwasJarFile,
844 websphereJarFile);
845 } catch (IOException renameException) {
846 log(renameException.getMessage(), Project.MSG_WARN);
847 rebuild = true;
848 }
849 }
850 }
851
852 return rebuild;
853 }
854
855
856 /**
857 * Helper method invoked by isRebuildRequired to get a ClassLoader for a
858 * Jar File passed to it.
859 *
860 * @param classjar java.io.File representing jar file to get classes from.
861 */
862 protected ClassLoader getClassLoaderFromJar(File classjar) throws IOException {
863 Path lookupPath = new Path(getTask().getProject());
864
865 lookupPath.setLocation(classjar);
866
867 Path classpath = getCombinedClasspath();
868
869 if (classpath != null) {
870 lookupPath.append(classpath);
871 }
872
873 return getTask().getProject().createClassLoader(lookupPath);
874 }
875}
876
Note: See TracBrowser for help on using the repository browser.