EMMA Coverage Report (generated Mon Oct 04 21:03:19 MDT 2004)
[all classes][biz.xsoftware.buildtemplate]

COVERAGE SUMMARY FOR SOURCE FILE [RunAnt.java]

nameclass, %method, %block, %line, %
RunAnt.java100% (2/2)89%  (8/9)93%  (401/430)89%  (82.3/92)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class RunAnt$ReadLogFromSocket100% (1/1)75%  (3/4)68%  (40/59)67%  (16/24)
waitForAllRead (): void 0%   (0/1)0%   (0/13)0%   (0/6)
run (): void 100% (1/1)40%  (4/10)60%  (3/5)
RunAnt$ReadLogFromSocket (RunAnt, ServerSocket): void 100% (1/1)100% (12/12)100% (4/4)
readAnt (): void 100% (1/1)100% (24/24)100% (9/9)
     
class RunAnt100% (1/1)100% (5/5)97%  (361/371)97%  (66.3/68)
destroy (): void 100% (1/1)70%  (7/10)75%  (3/4)
<static initializer> 100% (1/1)92%  (11/12)92%  (0.9/1)
runAntByForkingWithLogger (File, String []): void 100% (1/1)98%  (329/335)99%  (56.4/57)
RunAnt (): void 100% (1/1)100% (9/9)100% (4/4)
run (File, String []): void 100% (1/1)100% (5/5)100% (2/2)

1/*
2 * Created on Aug 31, 2004
3 *
4 * TODO To change the template for this generated file go to
5 * Window - Preferences - Java - Code Style - Code Templates
6 */
7package biz.xsoftware.buildtemplate;
8 
9import java.io.File;
10import java.io.IOException;
11import java.io.InputStream;
12import java.net.InetAddress;
13import java.net.InetSocketAddress;
14import java.net.ServerSocket;
15import java.net.Socket;
16import java.util.logging.Level;
17import java.util.logging.Logger;
18 
19/**
20 * @author Dean Hiller
21 *
22 * TODO To change the template for this generated type comment go to
23 * Window - Preferences - Java - Code Style - Code Templates
24 */
25public class RunAnt {
26 
27        private final static Logger log = Logger.getLogger(RunAnt.class.getName());
28        private Process p2 = null;
29        private boolean destroyed = false;
30        
31        public void run(File userDir, String[] args) throws Exception {
32                runAntByForkingWithLogger(userDir, args);
33        }
34        
35        synchronized public void destroy() {
36                if(p2 != null)
37                        p2.destroy();
38                destroyed = true;
39        }
40        
41        //can't use this method until jdk1.5 because there is no way to have
42        //stdout and stderr be printed in the order ant prints them.
43        //with 1.5, the new ProcessBuilder can be used...until then, can't
44        //fork ant as a separate process.
45        private void runAntByForkingWithLogger(File userDir, String[] args) throws Exception {
46                //tried to be lazy but that did not work....got exception in windows
47                //which we shouldn't get, must be bug in JVM, we should look in bug
48                //db.
49                
50                //ehhh, I am lazy right now, let's just exec the ant process
51                //later on, we could run ant in the same JVM.  Actually, running ant in the 
52                //same JVM doesn't work because on windows, all the jar files become locked
53                //and I can't delete them.  If I fork ant instead, I can delete the ant
54                //jars after I am done so the only thing left in someones view is the
55                //buildtemplate.jar plus a few project specific files that came from the template.
56                int numOurArgs = 13;
57                String[] cmdArray = new String[args.length+numOurArgs];
58                System.arraycopy(args, 0, cmdArray, numOurArgs, args.length);
59                
60                //Until everyone starts using jdk5.0, we cannot fork the ant process
61                //and redirect stdout and stderr to the same stream.  Instead, we specify ant
62                //to log to our very own AntSocketLogger, so while ant writes to the socket
63                //we will be reading from the socket, and when the build is finally finished,
64                //AntSocketLogger will close the socket letting us know the build is finished
65                InetAddress localHost = InetAddress.getByName("127.0.0.1");
66                ServerSocket s = new ServerSocket();
67                s.bind(new InetSocketAddress(localHost, 0));
68                int port = s.getLocalPort();
69                String host = s.getInetAddress().getHostAddress();
70                log.info("host="+host+" port="+port);
71                
72                ReadLogFromSocket readThread = new ReadLogFromSocket(s);
73                readThread.start();
74 
75                //ok, doing a "ant --execdebug" shows the long start ant command
76                //only on linux.  Windows does not have the same command
77                //so we will use what they do to stay platform independent and
78                //fork the ant process by calling "java xxxxx xx"
79                //NOTE: we have to fork so when the process returns we can delete
80                //the ant jars.
81                //
82                // "/cygdrive/c/ROOT/programs/jdk1.5.0//bin/java" 
83                // -classpath "c:/ROOT/programs/ant/lib/ant-launcher.jar" 
84                // -Dant.home="c:/ROOT/programs/ant" 
85                // -Dant.library.dir="c:/ROOT/programs/ant/lib" 
86                // -Dcygwin.user.home="C:/ROOT/programs/cygwin/home/Dean Hiller" 
87                // org.apache.tools.ant.launch.Launcher -lib ""        
88                
89                String f = File.separator;
90                String p = File.pathSeparator;
91                String base = userDir.getCanonicalPath();
92                String antDir = base+f+Main.TOOLS_DIR+f+"ant";
93                String antLib = antDir+f+"lib";
94                //crap...this will only work on windows, may need to check system
95                //properties and if windows, use 'ant.bat', else use 'ant' script instead
96                //the other option is to fork java -cp buildtemplate.jar com.avaya.ClassThatRunsAnt
97                int j = 0;
98                cmdArray[j++] = "java";
99                cmdArray[j++] = "-classpath";
100                cmdArray[j++] = antLib+f+"ant-launcher.jar";
101                cmdArray[j++] = "-Dant.home="+antDir;
102                cmdArray[j++] = "-Dant.library.dir="+antLib;
103                //cmdArray[j++] = "-Dcygwin.user.home=\""+System.getProperty("user.home")+"\"";
104                cmdArray[j++] = "-D"+AntSocketLogger.PORT_PROPERTY+"="+port;
105                cmdArray[j++] = "org.apache.tools.ant.launch.Launcher";
106                cmdArray[j++] = "-logger";
107                cmdArray[j++] = "biz.xsoftware.buildtemplate.AntSocketLogger";
108                cmdArray[j++] = "-lib";
109                cmdArray[j++] = base+f+Main.TEMPLATE_JAR_FILE;
110                cmdArray[j++] = "-f";
111                cmdArray[j++] = base+f+"bldfiles"+f+"build.xml";
112                        
113                try {
114                        Process p1 = Runtime.getRuntime().exec("chmod 755 "+cmdArray[0]);
115                        p1.waitFor();
116                } catch(Exception e) { /* gulp if on windows */ }
117                
118                String cmdString = "";
119                for(int i = 0; i < cmdArray.length; i++) {
120                        cmdString += cmdArray[i]+" ";
121                }
122                log.info("run ant. cmd="+cmdString);
123                log.fine("running ant in dir="+userDir.getCanonicalPath());
124                System.err.println();
125                synchronized(this) {
126                        if(!destroyed)
127                                p2 = Runtime.getRuntime().exec(cmdArray);
128                }
129                //If we fork, we need to deal with stdout and stderr, but we can't
130                //print them mixed which sucks.  In jdk5.0, we can print them mixed finally
131                InputStream in;
132                
133                log.fine("***********stdout****************");
134                in = p2.getInputStream();
135                Util.copyInToOut(in, System.err);
136                in.close();        
137                log.fine("***********stderr****************");
138                in = p2.getErrorStream();
139                Util.copyInToOut(in, System.err);
140                in.close();        
141                log.fine("***********done");
142                
143                log.finer("waiting for ant process");
144                //wait until ant is finished....we can wait until we have all the ant logs
145                //we do not need to wait for ant's process to finish.  should we do that too??
146                //DO NOT SYNCHRONIZE HERE AS DESTORY WILL NOT BE CALLABLE WHILE this is 
147                //waiting if there is a synchronization lock on this....
148                p2.waitFor();
149                p2 = null;
150                log.finer("wait for all read signal");
151                
152                //Unfortunately I could not find a way to open a socket in ant with the ant logger
153                //before a target started as I needed access to the project properties and some
154                //of the other methods in the Superclass Logger did not provide them in ant1.6.2.
155                //I think that is a bug with ant, but I did not investigate further into the issue.
156                //readThread.waitForAllRead();                
157        }
158        
159        private class ReadLogFromSocket extends Thread {
160                private ServerSocket serverSock;
161                private boolean allHasBeenRead = false;
162                
163                /**
164                 * @param s
165                 */
166                public ReadLogFromSocket(ServerSocket s) {
167                        serverSock = s;
168                }
169 
170                /* (non-Javadoc)
171                 * @see java.lang.Runnable#run()
172                 */
173                public void run() {
174                        try {
175                                readAnt();
176                        } catch(Exception e) {
177                                log.log(Level.WARNING, "Some kind of exception happenend", e);
178                        }
179                }
180                synchronized private void readAnt() throws IOException {
181                        log.finer("accepting incoming socket from ant");
182                        Socket s = serverSock.accept();
183                        log.finer("accepted socket");
184                        
185                        InputStream in = s.getInputStream();
186                        //AntSocketLogger is guaranteed to close the socket thereby releasing
187                        //copyInToOut and continuing on
188                        Util.copyInToOut(in, System.err);
189                        in.close();
190                        
191                        allHasBeenRead = true;
192                        this.notifyAll();
193                }
194                
195                synchronized public void waitForAllRead() {
196                        try {
197                                if(!allHasBeenRead) {
198                                        this.wait();
199                                }
200                        } catch(InterruptedException e) {
201                                log.log(Level.WARNING, "exception", e);
202                        }
203                }
204        }
205}

[all classes][biz.xsoftware.buildtemplate]
EMMA 2.0.4217 (C) Vladimir Roubtsov