1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* SonarQube is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.application;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
class EmbeddedTomcat {
public static final String TEMP_RELATIVE_PATH = "temp/tomcat";
private final Env env;
private Tomcat tomcat = null;
private Thread hook = null;
private boolean stopping = false;
EmbeddedTomcat(Env env) {
this.env = env;
}
void start() throws IOException, LifecycleException {
if (tomcat != null || hook != null) {
throw new IllegalStateException("Server is already started");
}
// '%2F' (slash /) and '%5C' (backslash \) are permitted as path delimiters in URLs
// See Ruby on Rails url_for
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");
// Required for webapp and logback xml files
System.setProperty("SONAR_HOME", env.rootDir().getAbsolutePath());
tomcat = new Tomcat();
// Initialize directories
String basedir = env.freshDir(TEMP_RELATIVE_PATH).getCanonicalPath();
tomcat.setBaseDir(basedir);
tomcat.getHost().setAppBase(basedir);
tomcat.getHost().setAutoDeploy(false);
tomcat.getHost().setCreateDirs(false);
tomcat.getHost().setDeployOnStartup(true);
Props props = Props.create(env);
Logging.configure(tomcat, env, props);
Connectors.configure(tomcat, props);
Webapp.configure(tomcat, env, props);
tomcat.start();
addShutdownHook();
tomcat.getServer().await();
// Shutdown command received
stop();
}
private void addShutdownHook() {
hook = new Thread() {
@Override
public void run() {
EmbeddedTomcat.this.doStop();
}
};
Runtime.getRuntime().addShutdownHook(hook);
}
void stop() {
removeShutdownHook();
doStop();
}
private synchronized void doStop() {
try {
if (tomcat != null && !stopping) {
stopping = true;
tomcat.stop();
tomcat.destroy();
}
tomcat = null;
stopping = false;
File tempDir = env.file(TEMP_RELATIVE_PATH);
FileUtils.deleteQuietly(tempDir);
} catch (LifecycleException e) {
throw new IllegalStateException("Fail to stop web server", e);
}
}
private void removeShutdownHook() {
if (hook != null && !hook.isAlive()) {
Runtime.getRuntime().removeShutdownHook(hook);
hook = null;
}
}
int port() {
Connector[] connectors = tomcat.getService().findConnectors();
if (connectors.length > 0) {
return connectors[0].getLocalPort();
}
return -1;
}
}
|