View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.start;
20  
21  import static org.eclipse.jetty.start.UsageException.*;
22  
23  import java.io.File;
24  import java.io.FileOutputStream;
25  import java.io.IOException;
26  import java.nio.file.Path;
27  import java.util.ArrayList;
28  import java.util.Collections;
29  import java.util.HashMap;
30  import java.util.HashSet;
31  import java.util.List;
32  import java.util.ListIterator;
33  import java.util.Map;
34  import java.util.Set;
35  import java.util.StringTokenizer;
36  
37  import org.eclipse.jetty.start.Props.Prop;
38  import org.eclipse.jetty.start.config.ConfigSource;
39  import org.eclipse.jetty.start.config.ConfigSources;
40  import org.eclipse.jetty.start.config.DirConfigSource;
41  
42  /**
43   * The Arguments required to start Jetty.
44   */
45  public class StartArgs
46  {
47      public static final String VERSION;
48  
49      static
50      {
51          String ver = System.getProperty("jetty.version",null);
52  
53          if (ver == null)
54          {
55              Package pkg = StartArgs.class.getPackage();
56              if ((pkg != null) && "Eclipse.org - Jetty".equals(pkg.getImplementationVendor()) && (pkg.getImplementationVersion() != null))
57              {
58                  ver = pkg.getImplementationVersion();
59              }
60          }
61  
62          if (ver == null)
63          {
64              ver = "TEST";
65          }
66  
67          VERSION = ver;
68          System.setProperty("jetty.version",VERSION);
69      }
70  
71      private static final String SERVER_MAIN = "org.eclipse.jetty.xml.XmlConfiguration";
72  
73      /** List of enabled modules */
74      private Set<String> modules = new HashSet<>();
75      /** Map of enabled modules to the source of where that activation occurred */
76      private Map<String, List<String>> sources = new HashMap<>();
77      /** Map of properties to where that property was declared */
78      private Map<String, String> propertySource = new HashMap<>();
79      /** List of all active [files] sections from enabled modules */
80      private List<FileArg> files = new ArrayList<>();
81      /** List of all active [lib] sectinos from enabled modules */
82      private Classpath classpath;
83      /** List of all active [xml] sections from enabled modules */
84      private List<Path> xmls = new ArrayList<>();
85      /** JVM arguments, found via commmand line and in all active [exec] sections from enabled modules */
86      private List<String> jvmArgs = new ArrayList<>();
87  
88      /** List of all xml references found directly on command line or start.ini */
89      private List<String> xmlRefs = new ArrayList<>();
90  
91      /** List of all property references found directly on command line or start.ini */
92      private List<String> propertyFileRefs = new ArrayList<>();
93      
94      /** List of all property files */
95      private List<Path> propertyFiles = new ArrayList<>();
96  
97      private Props properties = new Props();
98      private Set<String> systemPropertyKeys = new HashSet<>();
99      private List<String> rawLibs = new ArrayList<>();
100 
101     // jetty.base - build out commands
102     /** --add-to-startd=[module,[module]] */
103     private List<String> addToStartdIni = new ArrayList<>();
104     /** --add-to-start=[module,[module]] */
105     private List<String> addToStartIni = new ArrayList<>();
106 
107     // module inspection commands
108     /** --write-module-graph=[filename] */
109     private String moduleGraphFilename;
110 
111     /** Collection of all modules */
112     private Modules allModules;
113     /** Should the server be run? */
114     private boolean run = true;
115     private boolean download = false;
116     private boolean help = false;
117     private boolean stopCommand = false;
118     private boolean listModules = false;
119     private boolean listClasspath = false;
120     private boolean listConfig = false;
121     private boolean version = false;
122     private boolean dryRun = false;
123 
124     private boolean exec = false;
125 
126     public StartArgs()
127     {
128         classpath = new Classpath();
129     }
130 
131     private void addFile(String uriLocation)
132     {
133         FileArg arg = new FileArg(uriLocation);
134         if (!files.contains(arg))
135         {
136             files.add(arg);
137         }
138     }
139 
140     public void addSystemProperty(String key, String value)
141     {
142         this.systemPropertyKeys.add(key);
143         System.setProperty(key,value);
144     }
145 
146     private void addUniqueXmlFile(String xmlRef, Path xmlfile) throws IOException
147     {
148         if (!FS.canReadFile(xmlfile))
149         {
150             throw new IOException("Cannot read file: " + xmlRef);
151         }
152         xmlfile = FS.toRealPath(xmlfile);
153         if (!xmls.contains(xmlfile))
154         {
155             xmls.add(xmlfile);
156         }
157     }
158     
159     private void addUniquePropertyFile(String propertyFileRef, Path propertyFile) throws IOException
160     {
161         if (!FS.canReadFile(propertyFile))
162         {
163             throw new IOException("Cannot read file: " + propertyFileRef);
164         }
165         propertyFile = FS.toRealPath(propertyFile);
166         if (!propertyFiles.contains(propertyFile))
167         {
168             propertyFiles.add(propertyFile);
169         }
170     }
171 
172     public void dumpActiveXmls(BaseHome baseHome)
173     {
174         System.out.println();
175         System.out.println("Jetty Active XMLs:");
176         System.out.println("------------------");
177         if (xmls.isEmpty())
178         {
179             System.out.println(" (no xml files specified)");
180             return;
181         }
182 
183         for (Path xml : xmls)
184         {
185             System.out.printf(" %s%n",baseHome.toShortForm(xml.toAbsolutePath()));
186         }
187     }
188 
189     public void dumpEnvironment(BaseHome baseHome)
190     {
191         // Java Details
192         System.out.println();
193         System.out.println("Java Environment:");
194         System.out.println("-----------------");
195         dumpSystemProperty("java.home");
196         dumpSystemProperty("java.vm.vendor");
197         dumpSystemProperty("java.vm.version");
198         dumpSystemProperty("java.vm.name");
199         dumpSystemProperty("java.vm.info");
200         dumpSystemProperty("java.runtime.name");
201         dumpSystemProperty("java.runtime.version");
202         dumpSystemProperty("java.io.tmpdir");
203         dumpSystemProperty("user.dir");
204         dumpSystemProperty("user.language");
205         dumpSystemProperty("user.country");
206 
207         // Jetty Environment
208         System.out.println();
209         System.out.println("Jetty Environment:");
210         System.out.println("-----------------");
211         dumpProperty("jetty.version");
212         dumpProperty("jetty.home");
213         dumpProperty("jetty.base");
214         
215         // Jetty Configuration Environment
216         System.out.println();
217         System.out.println("Config Search Order:");
218         System.out.println("--------------------");
219         for (ConfigSource config : baseHome.getConfigSources())
220         {
221             System.out.printf(" %s",config.getId());
222             if (config instanceof DirConfigSource)
223             {
224                 DirConfigSource dirsource = (DirConfigSource)config;
225                 if (dirsource.isPropertyBased())
226                 {
227                     System.out.printf(" -> %s",dirsource.getDir());
228                 }
229             }
230             System.out.println();
231         }
232         
233         // Jetty Se
234         System.out.println();
235     }
236 
237     public void dumpJvmArgs()
238     {
239         System.out.println();
240         System.out.println("JVM Arguments:");
241         System.out.println("--------------");
242         if (jvmArgs.isEmpty())
243         {
244             System.out.println(" (no jvm args specified)");
245             return;
246         }
247 
248         for (String jvmArgKey : jvmArgs)
249         {
250             String value = System.getProperty(jvmArgKey);
251             if (value != null)
252             {
253                 System.out.printf(" %s = %s%n",jvmArgKey,value);
254             }
255             else
256             {
257                 System.out.printf(" %s%n",jvmArgKey);
258             }
259         }
260     }
261 
262     public void dumpProperties()
263     {
264         System.out.println();
265         System.out.println("Properties:");
266         System.out.println("-----------");
267 
268         List<String> sortedKeys = new ArrayList<>();
269         for (Prop prop : properties)
270         {
271             if (prop.origin.equals(Props.ORIGIN_SYSPROP))
272             {
273                 continue; // skip
274             }
275             sortedKeys.add(prop.key);
276         }
277 
278         if (sortedKeys.isEmpty())
279         {
280             System.out.println(" (no properties specified)");
281             return;
282         }
283 
284         Collections.sort(sortedKeys);
285 
286         for (String key : sortedKeys)
287         {
288             dumpProperty(key);
289         }
290     }
291 
292     private void dumpProperty(String key)
293     {
294         Prop prop = properties.getProp(key);
295         if (prop == null)
296         {
297             System.out.printf(" %s (not defined)%n",key);
298         }
299         else
300         {
301             System.out.printf(" %s = %s%n",key,properties.expand(prop.value));
302             if (StartLog.isDebugEnabled())
303             {
304                 System.out.printf("   origin: %s%n",prop.origin);
305                 while (prop.overrides != null)
306                 {
307                     prop = prop.overrides;
308                     System.out.printf("   (overrides)%n");
309                     System.out.printf("     %s = %s%n",key,properties.expand(prop.value));
310                     System.out.printf("     origin: %s%n",prop.origin);
311                 }
312             }
313         }
314     }
315 
316     public void dumpSystemProperties()
317     {
318         System.out.println();
319         System.out.println("System Properties:");
320         System.out.println("------------------");
321 
322         if (systemPropertyKeys.isEmpty())
323         {
324             System.out.println(" (no system properties specified)");
325             return;
326         }
327 
328         List<String> sortedKeys = new ArrayList<>();
329         sortedKeys.addAll(systemPropertyKeys);
330         Collections.sort(sortedKeys);
331 
332         for (String key : sortedKeys)
333         {
334             String value = System.getProperty(key);
335             System.out.printf(" %s = %s%n",key,properties.expand(value));
336         }
337     }
338 
339     private void dumpSystemProperty(String key)
340     {
341         System.out.printf(" %s = %s%n",key,System.getProperty(key));
342     }
343 
344     /**
345      * Ensure that the System Properties are set (if defined as a System property, or start.config property, or start.ini property)
346      * 
347      * @param key
348      *            the key to be sure of
349      */
350     private void ensureSystemPropertySet(String key)
351     {
352         if (systemPropertyKeys.contains(key))
353         {
354             return; // done
355         }
356 
357         if (properties.containsKey(key))
358         {
359             String val = properties.expand(properties.getString(key));
360             if (val == null)
361             {
362                 return; // no value to set
363             }
364             // setup system property
365             systemPropertyKeys.add(key);
366             System.setProperty(key,val);
367         }
368     }
369 
370     /**
371      * Expand any command line added <code>--lib</code> lib references.
372      * 
373      * @param baseHome
374      * @throws IOException
375      */
376     public void expandLibs(BaseHome baseHome) throws IOException
377     {
378         for (String rawlibref : rawLibs)
379         {
380             StartLog.debug("rawlibref = " + rawlibref);
381             String libref = properties.expand(rawlibref);
382             StartLog.debug("expanded = " + libref);
383             
384             // perform path escaping (needed by windows)
385             libref = libref.replaceAll("\\\\([^\\\\])","\\\\\\\\$1");
386             
387             for (Path libpath : baseHome.getPaths(libref))
388             {
389                 classpath.addComponent(libpath.toFile());
390             }
391         }
392     }
393 
394     /**
395      * Build up the Classpath and XML file references based on enabled Module list.
396      * 
397      * @param baseHome
398      * @param activeModules
399      * @throws IOException
400      */
401     public void expandModules(BaseHome baseHome, List<Module> activeModules) throws IOException
402     {
403         for (Module module : activeModules)
404         {
405             // Find and Expand Libraries
406             for (String rawlibref : module.getLibs())
407             {
408                 StartLog.debug("rawlibref = " + rawlibref);
409                 String libref = properties.expand(rawlibref);
410                 StartLog.debug("expanded = " + libref);
411 
412                 for (Path libpath : baseHome.getPaths(libref))
413                 {
414                     classpath.addComponent(libpath.toFile());
415                 }
416             }
417 
418             for (String jvmArg : module.getJvmArgs())
419             {
420                 exec = true;
421                 jvmArgs.add(jvmArg);
422             }
423 
424             // Find and Expand XML files
425             for (String xmlRef : module.getXmls())
426             {
427                 // Straight Reference
428                 Path xmlfile = baseHome.getPath(xmlRef);
429                 addUniqueXmlFile(xmlRef,xmlfile);
430             }
431 
432             // Register Download operations
433             for (String file : module.getFiles())
434             {
435                 StartLog.debug("Adding module specified file: %s",file);
436                 addFile(file);
437             }
438         }
439     }
440 
441     public List<String> getAddToStartdIni()
442     {
443         return addToStartdIni;
444     }
445 
446     public List<String> getAddToStartIni()
447     {
448         return addToStartIni;
449     }
450 
451     public Modules getAllModules()
452     {
453         return allModules;
454     }
455 
456     public Classpath getClasspath()
457     {
458         return classpath;
459     }
460 
461     public Set<String> getEnabledModules()
462     {
463         return this.modules;
464     }
465 
466     public List<FileArg> getFiles()
467     {
468         return files;
469     }
470 
471     public List<String> getJvmArgs()
472     {
473         return jvmArgs;
474     }
475 
476     public CommandLineBuilder getMainArgs(BaseHome baseHome, boolean addJavaInit) throws IOException
477     {
478         CommandLineBuilder cmd = new CommandLineBuilder();
479 
480         if (addJavaInit)
481         {
482             cmd.addRawArg(CommandLineBuilder.findJavaBin());
483 
484             for (String x : jvmArgs)
485             {
486                 cmd.addRawArg(x);
487             }
488 
489             cmd.addRawArg("-Djava.io.tmpdir=" + System.getProperty("java.io.tmpdir"));
490             cmd.addRawArg("-Djetty.home=" + baseHome.getHome());
491             cmd.addRawArg("-Djetty.base=" + baseHome.getBase());
492 
493             // System Properties
494             for (String propKey : systemPropertyKeys)
495             {
496                 String value = System.getProperty(propKey);
497                 cmd.addEqualsArg("-D" + propKey,value);
498             }
499 
500             cmd.addRawArg("-cp");
501             cmd.addRawArg(classpath.toString());
502             cmd.addRawArg(getMainClassname());
503         }
504 
505         // Special Stop/Shutdown properties
506         ensureSystemPropertySet("STOP.PORT");
507         ensureSystemPropertySet("STOP.KEY");
508         ensureSystemPropertySet("STOP.WAIT");
509 
510         // pass properties as args or as a file
511         if (dryRun || isExec())
512         {
513             for (Prop p : properties)
514                 cmd.addRawArg(CommandLineBuilder.quote(p.key)+"="+CommandLineBuilder.quote(p.value));
515         }
516         else if (properties.size() > 0)
517         {
518             File prop_file = File.createTempFile("start",".properties");
519             prop_file.deleteOnExit();
520             try (FileOutputStream out = new FileOutputStream(prop_file))
521             {
522                 properties.store(out,"start.jar properties");
523             }
524             cmd.addRawArg(prop_file.getAbsolutePath());
525         }
526 
527         for (Path xml : xmls)
528         {
529             cmd.addRawArg(xml.toAbsolutePath().toString());
530         }
531         
532         for (Path propertyFile : propertyFiles)
533         {
534             cmd.addRawArg(propertyFile.toAbsolutePath().toString());
535         }
536 
537         return cmd;
538     }
539 
540     public String getMainClassname()
541     {
542         String mainclass = System.getProperty("jetty.server",SERVER_MAIN);
543         return System.getProperty("main.class",mainclass);
544     }
545 
546     public String getModuleGraphFilename()
547     {
548         return moduleGraphFilename;
549     }
550 
551     public Props getProperties()
552     {
553         return properties;
554     }
555 
556     public List<String> getSources(String module)
557     {
558         return sources.get(module);
559     }
560 
561     public List<Path> getXmlFiles()
562     {
563         return xmls;
564     }
565 
566     public boolean hasJvmArgs()
567     {
568         return jvmArgs.size() > 0;
569     }
570 
571     public boolean hasSystemProperties()
572     {
573         for (String key : systemPropertyKeys)
574         {
575             // ignored keys
576             if ("jetty.home".equals(key) || "jetty.base".equals(key))
577             {
578                 // skip
579                 continue;
580             }
581             return true;
582         }
583         return false;
584     }
585 
586     public boolean isDownload()
587     {
588         return download;
589     }
590 
591     public boolean isDryRun()
592     {
593         return dryRun;
594     }
595 
596     public boolean isExec()
597     {
598         return exec;
599     }
600 
601     public boolean isHelp()
602     {
603         return help;
604     }
605 
606     public boolean isListClasspath()
607     {
608         return listClasspath;
609     }
610 
611     public boolean isListConfig()
612     {
613         return listConfig;
614     }
615 
616     public boolean isListModules()
617     {
618         return listModules;
619     }
620 
621     public boolean isRun()
622     {
623         return run;
624     }
625 
626     public boolean isStopCommand()
627     {
628         return stopCommand;
629     }
630 
631     public boolean isVersion()
632     {
633         return version;
634     }
635 
636     public void parse(ConfigSources sources)
637     {
638         ListIterator<ConfigSource> iter = sources.reverseListIterator();
639         while (iter.hasPrevious())
640         {
641             ConfigSource source = iter.previous();
642             for (RawArgs.Entry arg : source.getArgs())
643             {
644                 parse(arg.getLine(),arg.getOrigin());
645             }
646         }
647     }
648 
649     public void parse(final String rawarg, String source)
650     {
651         if (rawarg == null)
652         {
653             return;
654         }
655 
656         final String arg = rawarg.trim();
657 
658         if (arg.length() <= 0)
659         {
660             return;
661         }
662 
663         if (arg.startsWith("#"))
664         {
665             return;
666         }
667 
668         if ("--help".equals(arg) || "-?".equals(arg))
669         {
670             help = true;
671             run = false;
672             return;
673         }
674 
675         if ("--debug".equals(arg) || arg.startsWith("--start-log-file"))
676         {
677             // valid, but handled in StartLog instead
678             return;
679         }
680 
681         if (arg.startsWith("--include-jetty-dir="))
682         {
683             // valid, but handled in ConfigSources instead
684             return;
685         }
686 
687         if ("--stop".equals(arg))
688         {
689             stopCommand = true;
690             run = false;
691             return;
692         }
693 
694         if (arg.startsWith("--download="))
695         {
696             addFile(Props.getValue(arg));
697             run = false;
698             download = true;
699             return;
700         }
701 
702         if (arg.equals("--create-files"))
703         {
704             run = false;
705             download = true;
706             return;
707         }
708 
709         if ("--list-classpath".equals(arg) || "--version".equals(arg) || "-v".equals(arg) || "--info".equals(arg))
710         {
711             listClasspath = true;
712             run = false;
713             return;
714         }
715 
716         if ("--list-config".equals(arg))
717         {
718             listConfig = true;
719             run = false;
720             return;
721         }
722 
723         if ("--dry-run".equals(arg) || "--exec-print".equals(arg))
724         {
725             dryRun = true;
726             run = false;
727             return;
728         }
729 
730         // Enable forked execution of Jetty server
731         if ("--exec".equals(arg))
732         {
733             exec = true;
734             return;
735         }
736 
737         // Arbitrary Libraries
738         if (arg.startsWith("--lib="))
739         {
740             String cp = Props.getValue(arg);
741 
742             if (cp != null)
743             {
744                 StringTokenizer t = new StringTokenizer(cp,File.pathSeparator);
745                 while (t.hasMoreTokens())
746                 {
747                     rawLibs.add(t.nextToken());
748                 }
749             }
750             return;
751         }
752 
753         // Module Management
754         if ("--list-modules".equals(arg))
755         {
756             listModules = true;
757             run = false;
758             return;
759         }
760 
761         // jetty.base build-out : add to ${jetty.base}/start.d/
762         if (arg.startsWith("--add-to-startd="))
763         {
764             addToStartdIni.addAll(Props.getValues(arg));
765             run = false;
766             download = true;
767             return;
768         }
769 
770         // jetty.base build-out : add to ${jetty.base}/start.ini
771         if (arg.startsWith("--add-to-start="))
772         {
773             addToStartIni.addAll(Props.getValues(arg));
774             run = false;
775             download = true;
776             return;
777         }
778 
779         // Enable a module
780         if (arg.startsWith("--module="))
781         {
782             for (String moduleName : Props.getValues(arg))
783             {
784                 modules.add(moduleName);
785                 List<String> list = sources.get(moduleName);
786                 if (list == null)
787                 {
788                     list = new ArrayList<String>();
789                     sources.put(moduleName,list);
790                 }
791                 list.add(source);
792             }
793             return;
794         }
795 
796         // Create graphviz output of module graph
797         if (arg.startsWith("--write-module-graph="))
798         {
799             this.moduleGraphFilename = Props.getValue(arg);
800             run = false;
801             return;
802         }
803 
804         // Start property (syntax similar to System property)
805         if (arg.startsWith("-D"))
806         {
807             String[] assign = arg.substring(2).split("=",2);
808             systemPropertyKeys.add(assign[0]);
809             switch (assign.length)
810             {
811                 case 2:
812                     System.setProperty(assign[0],assign[1]);
813                     setProperty(assign[0],assign[1],source);
814                     break;
815                 case 1:
816                     System.setProperty(assign[0],"");
817                     setProperty(assign[0],"",source);
818                     break;
819                 default:
820                     break;
821             }
822             return;
823         }
824 
825         // Anything else with a "-" is considered a JVM argument
826         if (arg.startsWith("-"))
827         {
828             // Only add non-duplicates
829             if (!jvmArgs.contains(arg))
830             {
831                 jvmArgs.add(arg);
832             }
833             return;
834         }
835 
836         // Is this a raw property declaration?
837         int idx = arg.indexOf('=');
838         if (idx >= 0)
839         {
840             String key = arg.substring(0,idx);
841             String value = arg.substring(idx + 1);
842 
843             if (propertySource.containsKey(key))
844             {
845                 StartLog.warn("Property %s in %s already set in %s",key,source,propertySource.get(key));
846             }
847             propertySource.put(key,source);
848 
849             if ("OPTION".equals(key) || "OPTIONS".equals(key))
850             {
851                 StringBuilder warn = new StringBuilder();
852                 warn.append("The behavior of the argument ");
853                 warn.append(arg).append(" (seen in ").append(source);
854                 warn.append(") has changed, and is now considered a normal property.  ");
855                 warn.append(key).append(" no longer controls what libraries are on your classpath,");
856                 warn.append(" use --module instead. See --help for details.");
857                 StartLog.warn(warn.toString());
858             }
859 
860             setProperty(key,value,source);
861             return;
862         }
863 
864         // Is this an xml file?
865         if (FS.isXml(arg))
866         {
867             // only add non-duplicates
868             if (!xmlRefs.contains(arg))
869             {
870                 xmlRefs.add(arg);
871             }
872             return;
873         }
874         
875         if (FS.isPropertyFile(arg))
876         {
877             // only add non-duplicates
878             if (!propertyFileRefs.contains(arg))
879             {
880             	propertyFileRefs.add(arg);
881             }
882         	return;
883         }
884 
885         // Anything else is unrecognized
886         throw new UsageException(ERR_BAD_ARG,"Unrecognized argument: \"%s\" in %s",arg,source);
887     }
888 
889     public void resolveExtraXmls(BaseHome baseHome) throws IOException
890     {
891         // Find and Expand XML files
892         for (String xmlRef : xmlRefs)
893         {
894             // Straight Reference
895             Path xmlfile = baseHome.getPath(xmlRef);
896             if (!FS.exists(xmlfile))
897             {
898                 xmlfile = baseHome.getPath("etc/" + xmlRef);
899             }
900             addUniqueXmlFile(xmlRef,xmlfile);
901         }
902     }
903     
904     public void resolvePropertyFiles(BaseHome baseHome) throws IOException
905     {
906         // Find and Expand property files
907         for (String propertyFileRef : propertyFileRefs)
908         {
909             // Straight Reference
910             Path propertyFile = baseHome.getPath(propertyFileRef);
911             if (!FS.exists(propertyFile))
912             {
913             	propertyFile = baseHome.getPath("etc/" + propertyFileRef);
914             }
915             addUniquePropertyFile(propertyFileRef,propertyFile);
916         }
917     }
918 
919     public void setAllModules(Modules allModules)
920     {
921         this.allModules = allModules;
922     }
923 
924     private void setProperty(String key, String value, String source)
925     {
926         // Special / Prevent override from start.ini's
927         if (key.equals("jetty.home"))
928         {
929             properties.setProperty("jetty.home",System.getProperty("jetty.home"),source);
930             return;
931         }
932 
933         // Special / Prevent override from start.ini's
934         if (key.equals("jetty.base"))
935         {
936             properties.setProperty("jetty.base",System.getProperty("jetty.base"),source);
937             return;
938         }
939 
940         // Normal
941         properties.setProperty(key,value,source);
942     }
943 
944     public void setRun(boolean run)
945     {
946         this.run = run;
947     }
948 
949     @Override
950     public String toString()
951     {
952         StringBuilder builder = new StringBuilder();
953         builder.append("StartArgs [enabledModules=");
954         builder.append(modules);
955         builder.append(", xmlRefs=");
956         builder.append(xmlRefs);
957         builder.append(", properties=");
958         builder.append(properties);
959         builder.append(", jvmArgs=");
960         builder.append(jvmArgs);
961         builder.append("]");
962         return builder.toString();
963     }
964 }