You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

WeavingURLClassLoaderTest.java 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. /* *******************************************************************
  2. * Copyright (c) 2004 IBM Corporation
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * Matthew Webster initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.loadtime;
  13. import java.io.File;
  14. import java.lang.reflect.InvocationTargetException;
  15. import java.lang.reflect.Method;
  16. import java.net.URL;
  17. import java.util.Enumeration;
  18. import java.util.Properties;
  19. import junit.framework.TestCase;
  20. import org.aspectj.bridge.AbortException;
  21. import org.aspectj.testing.util.TestUtil.TestError;
  22. import org.aspectj.util.FileUtil;
  23. import org.aspectj.weaver.BcweaverTests;
  24. import org.aspectj.weaver.tools.WeavingAdaptor;
  25. /**
  26. * @author websterm
  27. *
  28. * To change the template for this generated type comment go to
  29. * Window>Preferences>Java>Code Generation>Code and Comments
  30. */
  31. public class WeavingURLClassLoaderTest extends TestCase {
  32. private final static String ASPECTJRT = "../runtime/bin";
  33. private final static String CLASSES_JAR = BcweaverTests.TESTDATA_PATH + "/ltw-classes.jar";
  34. private final static String WOVEN_JAR = BcweaverTests.TESTDATA_PATH + "/ltw-woven.jar";
  35. private final static String JUNK_JAR = BcweaverTests.TESTDATA_PATH + "/ltw-junk.jar";
  36. private final static String ADVICE_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-aspects.jar";
  37. private final static String DW_ADVICE_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-dwaspects.jar";
  38. private final static String DE_ADVICE_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-deaspects.jar";
  39. private final static String AROUNDCLOSURE_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-acaspects.jar";
  40. private final static String ITD_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-itdaspects.jar";
  41. private final static String PER_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-peraspects.jar";
  42. private final static String TEST_BASE = BcweaverTests.TESTDATA_PATH + "/WeavingURLClassLoaderTest/builtLibs";
  43. private final static String NULL = "null";
  44. private Properties savedProperties;
  45. public WeavingURLClassLoaderTest(String name) {
  46. super(name);
  47. }
  48. public void testLoadClass () {
  49. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,"");
  50. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,CLASSES_JAR);
  51. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  52. try {
  53. Class clazz = loader.loadClass("LTWHelloWorld");
  54. invokeMain(clazz,new String[] {});
  55. }
  56. catch (Exception ex) {
  57. fail(ex.toString());
  58. }
  59. }
  60. /*
  61. * We won't get an exception because the aspect path is empty and there is
  62. * no aop.xml file so the weaver will be disabled and no reweaving will
  63. * take place
  64. */
  65. public void testLoadWovenClass () {
  66. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,"");
  67. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,WOVEN_JAR);
  68. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  69. try {
  70. Class clazz = loader.loadClass("LTWHelloWorld");
  71. invokeMain(clazz,new String[] { "LTWAspect" });
  72. }
  73. catch (Exception ex) {
  74. fail(ex.toString());
  75. }
  76. }
  77. /*
  78. * We get an exception because the class was not built reweavable
  79. */
  80. public void testWeaveWovenClass () {
  81. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS);
  82. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + WOVEN_JAR);
  83. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  84. try {
  85. loader.loadClass("LTWHelloWorld");
  86. fail("Expecting org.aspectj.bridge.AbortException");
  87. }
  88. catch (Exception ex) {
  89. assertTrue("Expecting org.aspectj.bridge.AbortException caught " + ex,(ex instanceof AbortException));
  90. }
  91. }
  92. public void testWeavingURLClassLoader () {
  93. URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
  94. URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT));
  95. URL aspects = FileUtil.getFileURL(new File(ADVICE_ASPECTS));
  96. URL[] classURLs = new URL[] { aspects, classes, aspectjrt };
  97. URL[] aspectURLs = new URL[] { aspects };
  98. WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
  99. try {
  100. Class clazz = loader.loadClass("LTWHelloWorld");
  101. invokeMain(clazz,new String[] { "LTWAspect" });
  102. }
  103. catch (Exception ex) {
  104. fail(ex.toString());
  105. }
  106. }
  107. public void testWeaveAdvice () {
  108. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS);
  109. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + CLASSES_JAR + File.pathSeparator + ASPECTJRT);
  110. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  111. try {
  112. Class clazz = loader.loadClass("LTWHelloWorld");
  113. invokeMain(clazz,new String[] { "LTWAspect" });
  114. }
  115. catch (Exception ex) {
  116. fail(ex.toString());
  117. }
  118. }
  119. public void testWeaveAdviceWithVerbose () {
  120. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS);
  121. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + CLASSES_JAR + File.pathSeparator + ASPECTJRT);
  122. setSystemProperty(WeavingAdaptor.WEAVING_ADAPTOR_VERBOSE,"true");
  123. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  124. try {
  125. Class clazz = loader.loadClass("LTWHelloWorld");
  126. invokeMain(clazz,new String[] { "LTWAspect" });
  127. }
  128. catch (Exception ex) {
  129. fail(ex.toString());
  130. }
  131. }
  132. public void testWeaveAdviceWithWeaveInfo () {
  133. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS);
  134. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + CLASSES_JAR + File.pathSeparator + ASPECTJRT);
  135. setSystemProperty(WeavingAdaptor.SHOW_WEAVE_INFO_PROPERTY,"true");
  136. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  137. try {
  138. Class clazz = loader.loadClass("LTWHelloWorld");
  139. invokeMain(clazz,new String[] { "LTWAspect" });
  140. }
  141. catch (Exception ex) {
  142. fail(ex.toString());
  143. }
  144. }
  145. public void testWeaveDeclareWarningAdvice () {
  146. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,DW_ADVICE_ASPECTS);
  147. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,DW_ADVICE_ASPECTS + File.pathSeparator + CLASSES_JAR);
  148. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  149. try {
  150. Class clazz = loader.loadClass("LTWHelloWorld");
  151. invokeMain(clazz,new String[] {} );
  152. }
  153. catch (Exception ex) {
  154. fail(ex.toString());
  155. }
  156. }
  157. public void testWeaveDeclareErrorAdvice () {
  158. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,DE_ADVICE_ASPECTS);
  159. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,DE_ADVICE_ASPECTS + File.pathSeparator + CLASSES_JAR);
  160. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  161. try {
  162. Class clazz = loader.loadClass("LTWHelloWorld");
  163. invokeMain(clazz,new String[] {} );
  164. fail("Expecting org.aspectj.bridge.AbortException");
  165. }
  166. catch (Exception ex) {
  167. assertTrue("Expecting org.aspectj.bridge.AbortException caught " + ex,(ex instanceof AbortException));
  168. }
  169. }
  170. public void testWeaveAroundClosure () {
  171. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,AROUNDCLOSURE_ASPECTS);
  172. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,AROUNDCLOSURE_ASPECTS + File.pathSeparator + CLASSES_JAR + File.pathSeparator + ASPECTJRT);
  173. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  174. try {
  175. Class clazz = loader.loadClass("LTWHelloWorld");
  176. invokeMain(clazz,new String[] { "LTWAroundClosure" });
  177. }
  178. catch (Exception ex) {
  179. fail(ex.toString());
  180. }
  181. }
  182. public void testWeavingITD () {
  183. URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
  184. URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT));
  185. URL aspects = FileUtil.getFileURL(new File(ITD_ASPECTS));
  186. URL[] classURLs = new URL[] { aspects, classes, aspectjrt };
  187. URL[] aspectURLs = new URL[] { aspects };
  188. WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
  189. try {
  190. Class clazz = loader.loadClass("LTWHelloWorld");
  191. invokeMain(clazz,new String[] { "LTWInterfaceITD", "LTWFieldITD", "LTWMethodITD" });
  192. }
  193. catch (Exception ex) {
  194. fail(ex.toString());
  195. }
  196. }
  197. public void testWeavingPer () {
  198. URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
  199. URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT));
  200. URL aspects = FileUtil.getFileURL(new File(PER_ASPECTS));
  201. URL[] classURLs = new URL[] { aspects, classes, aspectjrt };
  202. URL[] aspectURLs = new URL[] { aspects };
  203. WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
  204. try {
  205. Class clazz = loader.loadClass("LTWHelloWorld");
  206. invokeMain(clazz,new String[] { "LTWPerthis" });
  207. }
  208. catch (Exception ex) {
  209. fail(ex.toString());
  210. }
  211. }
  212. public void testWeavingAspects () {
  213. URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
  214. URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT));
  215. URL aspects1 = FileUtil.getFileURL(new File(ADVICE_ASPECTS));
  216. URL aspects2 = FileUtil.getFileURL(new File(AROUNDCLOSURE_ASPECTS));
  217. URL aspects3 = FileUtil.getFileURL(new File(ITD_ASPECTS));
  218. URL aspects4 = FileUtil.getFileURL(new File(PER_ASPECTS));
  219. URL[] classURLs = new URL[] { aspects1, aspects2, aspects3, aspects4, classes, aspectjrt };
  220. URL[] aspectURLs = new URL[] { aspects1, aspects2, aspects3, aspects4 };
  221. WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
  222. try {
  223. Class clazz = loader.loadClass("LTWHelloWorld");
  224. invokeMain(clazz,new String[] { "LTWAspect", "LTWAroundClosure", "LTWPerthis", "LTWInterfaceITD", "LTWFieldITD", "LTWMethodITD", "LTWPerthis"});
  225. }
  226. catch (Exception ex) {
  227. fail(ex.toString());
  228. }
  229. }
  230. public void testJunkJar () {
  231. File junkJar = new File(JUNK_JAR);
  232. assertFalse(junkJar + " should not exist",junkJar.exists());
  233. URL classes = FileUtil.getFileURL(junkJar);
  234. URL[] classURLs = new URL[] { classes };
  235. URL[] aspectURLs = new URL[] { };
  236. WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
  237. try {
  238. loader.loadClass("LTWHelloWorld");
  239. fail("Expecting java.lang.ClassNotFoundException");
  240. }
  241. catch (Exception ex) {
  242. assertTrue("Expecting java.lang.ClassNotFoundException caught " + ex,(ex instanceof ClassNotFoundException));
  243. }
  244. }
  245. public void testJunkAspectJar () {
  246. File junkJar = new File(JUNK_JAR);
  247. assertFalse(junkJar + " should not exist",junkJar.exists());
  248. URL aspects = FileUtil.getFileURL(junkJar);
  249. URL[] classURLs = new URL[] { aspects };
  250. URL[] aspectURLs = new URL[] { aspects };
  251. try {
  252. new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
  253. fail("Expecting org.aspectj.bridge.AbortException");
  254. }
  255. catch (Exception ex) {
  256. assertTrue("Expecting org.aspectj.bridge.AbortException caught " + ex,(ex instanceof org.aspectj.bridge.AbortException));
  257. }
  258. }
  259. public void testAddURL () {
  260. URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
  261. URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT));
  262. URL aspects = FileUtil.getFileURL(new File(ADVICE_ASPECTS));
  263. URL[] classURLs = new URL[] { aspects, aspectjrt };
  264. URL[] aspectURLs = new URL[] { aspects };
  265. WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
  266. loader.addURL(classes);
  267. try {
  268. Class clazz = loader.loadClass("LTWHelloWorld");
  269. invokeMain(clazz,new String[] { "LTWAspect" });
  270. }
  271. catch (Exception ex) {
  272. fail(ex.toString());
  273. }
  274. }
  275. public void testParentChild() {
  276. URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
  277. URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT));
  278. URL aspects = FileUtil.getFileURL(new File(ADVICE_ASPECTS));
  279. URL[] classURLs = new URL[] { aspects, aspectjrt };
  280. URL[] aspectURLs = new URL[] { aspects };
  281. WeavingURLClassLoader parent = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
  282. classURLs = new URL[] { classes };
  283. aspectURLs = new URL[] { };
  284. WeavingURLClassLoader child = new WeavingURLClassLoader(classURLs,aspectURLs,parent);
  285. try {
  286. Class clazz = child.loadClass("LTWHelloWorld");
  287. invokeMain(clazz,new String[] { "LTWAspect" });
  288. }
  289. catch (Exception ex) {
  290. fail(ex.toString());
  291. }
  292. }
  293. /*
  294. * Aspects on ASPECTPATH but missing from CLASSPATH
  295. */
  296. public void testIncompletePath () {
  297. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS);
  298. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,CLASSES_JAR);
  299. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  300. try {
  301. Class clazz = loader.loadClass("LTWHelloWorld");
  302. invokeMain(clazz,new String[] { "LTWAspect" });
  303. fail("Expecting java.lang.NoClassDefFoundError");
  304. }
  305. catch (Exception ex) {
  306. assertTrue("Expecting java.lang.NoClassDefFoundError but caught " + ex,ex.getMessage().contains("java.lang.NoClassDefFoundError"));
  307. }
  308. }
  309. /*
  310. * Ensure package object is correct
  311. */
  312. public void testPackage () {
  313. setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,"");
  314. setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,CLASSES_JAR);
  315. WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
  316. try {
  317. Class clazz = loader.loadClass("ltw.LTWPackageTest");
  318. invokeMain(clazz,new String[] { });
  319. Package pakkage = clazz.getPackage();
  320. assertTrue("Expected 'ltw' got " + pakkage,(pakkage != null));
  321. }
  322. catch (Exception ex) {
  323. fail(ex.toString());
  324. }
  325. }
  326. public void testZipAspects() {
  327. try {
  328. doTestZipAspects(TEST_BASE + "/aspect.zip");
  329. } catch (Error ex) {
  330. failWithException(ex);
  331. } catch (Exception ex) {
  332. failWithException(ex);
  333. }
  334. }
  335. public void testJarAspects() {
  336. try {
  337. doTestZipAspects(TEST_BASE + "/aspect.jar");
  338. } catch (Error ex) {
  339. failWithException(ex);
  340. } catch (Exception ex) {
  341. failWithException(ex);
  342. }
  343. }
  344. /** PR#106736 */
  345. public void testClassAspects() {
  346. try {
  347. doTestZipAspects(TEST_BASE + "/classes");
  348. } catch (Error ex) {
  349. failWithException(ex);
  350. } catch (Exception ex) {
  351. failWithException(ex);
  352. }
  353. }
  354. public void testZipJarAspectsTest() {
  355. try {
  356. doTestZipAspectsTest();
  357. // bug: doTestZipAspects("") attempts to load packag.Aspect?
  358. fail("expected error to be thrown");
  359. } catch (InvocationTargetException ex) {
  360. // expecting error
  361. assertTrue(ex.getTargetException() instanceof Error);
  362. } catch (RuntimeException ex) {
  363. // expecting error
  364. String message = ex.getMessage();
  365. // expecting error - seems to be wrapped wrong
  366. if (-1 == message.indexOf("around advice")) {
  367. failWithException(ex);
  368. }
  369. } catch (Error ex) {
  370. failWithException(ex);
  371. } catch (Exception ex) {
  372. failWithException(ex);
  373. }
  374. }
  375. private void doTestZipAspects(String aspectLib) throws Exception {
  376. File classZip = new File(TEST_BASE + "/main.zip");
  377. File zipLib = new File(aspectLib);
  378. URL classes = FileUtil.getFileURL(classZip);
  379. URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT));
  380. URL aspects = FileUtil.getFileURL(zipLib);
  381. URL[] classURLs = new URL[] { aspects, classes, aspectjrt };
  382. URL[] aspectURLs = new URL[] { aspects };
  383. ClassLoader parent = getClass().getClassLoader();
  384. WeavingURLClassLoader loader
  385. = new WeavingURLClassLoader(classURLs, aspectURLs, parent);
  386. Class clazz = loader.loadClass("packag.Main");
  387. invokeMain(clazz,new String[] { });
  388. // throws Error unless advice applies
  389. }
  390. private void doTestZipAspectsTest() throws Exception {
  391. URL classes = FileUtil.getFileURL(new File(TEST_BASE + "/main.zip"));
  392. URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT));
  393. URL[] classURLs = new URL[] { classes, aspectjrt };
  394. ClassLoader parent = getClass().getClassLoader();
  395. WeavingURLClassLoader loader
  396. = new WeavingURLClassLoader(classURLs, new URL[] { }, parent);
  397. Class clazz = loader.loadClass("packag.Main");
  398. invokeMain(clazz,new String[] { });
  399. // throws Error because advice does not apply
  400. }
  401. private void failWithException(Throwable t) {
  402. throw new TestError(t.getMessage(), t);
  403. }
  404. public static void invokeMain (Class clazz, String[] args)
  405. {
  406. Class[] paramTypes = new Class[1];
  407. paramTypes[0] = args.getClass();
  408. try {
  409. Method method = clazz.getDeclaredMethod("main",paramTypes);
  410. Object[] params = new Object[1];
  411. params[0] = args;
  412. method.invoke(null,params);
  413. }
  414. catch (InvocationTargetException ex) {
  415. Throwable targetException = ex.getTargetException();
  416. if (targetException instanceof RuntimeException) throw (RuntimeException)ex.getTargetException();
  417. else throw new RuntimeException(ex.getTargetException().toString());
  418. }
  419. catch (Exception ex) {
  420. throw new RuntimeException(ex.toString());
  421. }
  422. }
  423. private void setSystemProperty (String key, String value) {
  424. Properties systemProperties = System.getProperties();
  425. copyProperty(key,systemProperties,savedProperties);
  426. systemProperties.setProperty(key,value);
  427. }
  428. private static void copyProperty (String key, Properties from, Properties to) {
  429. String value = from.getProperty(key,NULL);
  430. to.setProperty(key,value);
  431. }
  432. protected void setUp() throws Exception {
  433. super.setUp();
  434. savedProperties = new Properties();
  435. }
  436. protected void tearDown() throws Exception {
  437. super.tearDown();
  438. /* Restore system properties */
  439. Properties systemProperties = System.getProperties();
  440. for (Enumeration enu = savedProperties.keys(); enu.hasMoreElements(); ) {
  441. String key = (String)enu.nextElement();
  442. String value = savedProperties.getProperty(key);
  443. if (value == NULL) systemProperties.remove(key);
  444. else systemProperties.setProperty(key,value);
  445. }
  446. }
  447. }