warbler 1.3.6 → 1.3.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.travis.yml +21 -8
- data/Gemfile +4 -7
- data/LICENSE.txt +1 -1
- data/README.rdoc +95 -105
- data/Rakefile +4 -3
- data/ext/JarMain.java +184 -75
- data/ext/WarMain.java +194 -65
- data/ext/WarblerJar.java +11 -1
- data/lib/warbler.rb +2 -1
- data/lib/warbler/application.rb +4 -1
- data/lib/warbler/config.rb +14 -3
- data/lib/warbler/jar.rb +10 -2
- data/lib/warbler/task.rb +7 -7
- data/lib/warbler/templates/jar.erb +3 -2
- data/lib/warbler/templates/war.erb +1 -3
- data/lib/warbler/traits/bundler.rb +11 -3
- data/lib/warbler/traits/gemspec.rb +1 -1
- data/lib/warbler/traits/jar.rb +5 -2
- data/lib/warbler/traits/nogemspec.rb +7 -2
- data/lib/warbler/traits/war.rb +13 -2
- data/lib/warbler/version.rb +1 -1
- data/lib/warbler/web_server.rb +2 -2
- data/lib/warbler_jar.jar +0 -0
- data/spec/sample_war/Rakefile +5 -1
- data/spec/sample_war/lib/ruby_one_nine.rb +8 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/warbler/application_spec.rb +5 -5
- data/spec/warbler/bundler_spec.rb +47 -20
- data/spec/warbler/config_spec.rb +3 -1
- data/spec/warbler/jar_spec.rb +25 -4
- data/spec/warbler/task_spec.rb +17 -1
- data/warble.rb +6 -2
- data/warbler.gemspec +21 -21
- metadata +286 -257
- data/Gemfile.lock +0 -41
data/ext/WarMain.java
CHANGED
@@ -5,16 +5,22 @@
|
|
5
5
|
* See the file LICENSE.txt for details.
|
6
6
|
*/
|
7
7
|
|
8
|
-
import java.net.URLClassLoader;
|
9
|
-
import java.net.URL;
|
10
8
|
import java.lang.reflect.Method;
|
11
|
-
import java.io.IOException;
|
12
9
|
import java.io.InputStream;
|
10
|
+
import java.io.ByteArrayInputStream;
|
11
|
+
import java.io.SequenceInputStream;
|
13
12
|
import java.io.File;
|
13
|
+
import java.io.FileNotFoundException;
|
14
14
|
import java.io.FileOutputStream;
|
15
|
+
import java.net.URI;
|
16
|
+
import java.net.URLClassLoader;
|
17
|
+
import java.net.URL;
|
15
18
|
import java.util.Arrays;
|
19
|
+
import java.util.List;
|
16
20
|
import java.util.Properties;
|
17
21
|
import java.util.Map;
|
22
|
+
import java.util.jar.JarEntry;
|
23
|
+
import java.util.Set;
|
18
24
|
|
19
25
|
/**
|
20
26
|
* Used as a Main-Class in the manifest for a .war file, so that you can run
|
@@ -52,32 +58,48 @@ import java.util.Map;
|
|
52
58
|
* jetty.home = {{webroot}}
|
53
59
|
* </pre>
|
54
60
|
*/
|
55
|
-
public class WarMain
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
61
|
+
public class WarMain extends JarMain {
|
62
|
+
|
63
|
+
static final String MAIN = "/" + WarMain.class.getName().replace('.', '/') + ".class";
|
64
|
+
static final String WEBSERVER_PROPERTIES = "/WEB-INF/webserver.properties";
|
65
|
+
static final String WEBSERVER_JAR = "/WEB-INF/webserver.jar";
|
66
|
+
|
67
|
+
// jruby arguments, consider the following command :
|
68
|
+
// `java -jar rails.was --1.9 -S rake db:migrate`
|
69
|
+
// arguments == [ "--1.9" ]
|
70
|
+
// executable == "rake"
|
71
|
+
// executableArgv == [ "db:migrate" ]
|
72
|
+
private final String[] arguments;
|
73
|
+
// null to launch webserver or != null to run a executable e.g. rake
|
74
|
+
private final String executable;
|
75
|
+
private final String[] executableArgv;
|
76
|
+
|
63
77
|
private File webroot;
|
64
78
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
79
|
+
WarMain(final String[] args) {
|
80
|
+
super(args);
|
81
|
+
final List<String> argsList = Arrays.asList(args);
|
82
|
+
final int sIndex = argsList.indexOf("-S");
|
83
|
+
if ( sIndex == -1 ) {
|
84
|
+
executable = null; executableArgv = null; arguments = null;
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
if ( args.length == sIndex + 1 || args[sIndex + 1].isEmpty() ) {
|
88
|
+
throw new IllegalArgumentException("missing executable after -S");
|
89
|
+
}
|
90
|
+
arguments = argsList.subList(0, sIndex).toArray(new String[0]);
|
91
|
+
executable = argsList.get(sIndex + 1);
|
92
|
+
executableArgv = argsList.subList(sIndex + 2, argsList.size()).toArray(new String[0]);
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
private URL extractWebserver() throws Exception {
|
71
97
|
this.webroot = File.createTempFile("warbler", "webroot");
|
72
98
|
this.webroot.delete();
|
73
99
|
this.webroot.mkdirs();
|
74
|
-
this.webroot = new File(this.webroot, new File(
|
100
|
+
this.webroot = new File(this.webroot, new File(archive).getName());
|
75
101
|
debug("webroot directory is " + this.webroot.getPath());
|
76
|
-
|
77
|
-
}
|
78
|
-
|
79
|
-
private URL extractWebserver() throws Exception {
|
80
|
-
InputStream jarStream = new URL("jar:" + path.replace(MAIN, WEBSERVER_JAR)).openStream();
|
102
|
+
InputStream jarStream = new URI("jar", entryPath(WEBSERVER_JAR), null).toURL().openStream();
|
81
103
|
File jarFile = File.createTempFile("webserver", ".jar");
|
82
104
|
jarFile.deleteOnExit();
|
83
105
|
FileOutputStream outStream = new FileOutputStream(jarFile);
|
@@ -99,13 +121,12 @@ public class WarMain implements Runnable {
|
|
99
121
|
Properties props = new Properties();
|
100
122
|
try {
|
101
123
|
InputStream is = getClass().getResourceAsStream(WEBSERVER_PROPERTIES);
|
102
|
-
props.load(is);
|
103
|
-
} catch (Exception e) {
|
104
|
-
}
|
124
|
+
if ( is != null ) props.load(is);
|
125
|
+
} catch (Exception e) { }
|
105
126
|
|
106
127
|
for (Map.Entry entry : props.entrySet()) {
|
107
128
|
String val = (String) entry.getValue();
|
108
|
-
val = val.replace("{{warfile}}",
|
129
|
+
val = val.replace("{{warfile}}", archive).replace("{{webroot}}", webroot.getAbsolutePath());
|
109
130
|
entry.setValue(val);
|
110
131
|
}
|
111
132
|
|
@@ -119,7 +140,7 @@ public class WarMain implements Runnable {
|
|
119
140
|
return props;
|
120
141
|
}
|
121
142
|
|
122
|
-
private void
|
143
|
+
private void launchWebServer(URL jar) throws Exception {
|
123
144
|
URLClassLoader loader = new URLClassLoader(new URL[] {jar});
|
124
145
|
Thread.currentThread().setContextClassLoader(loader);
|
125
146
|
Properties props = getWebserverProperties();
|
@@ -130,66 +151,174 @@ public class WarMain implements Runnable {
|
|
130
151
|
+ " is missing 'mainclass' property)");
|
131
152
|
}
|
132
153
|
Class klass = Class.forName(mainClass, true, loader);
|
133
|
-
Method main = klass.getDeclaredMethod("main", new Class[] {String[].class});
|
134
|
-
String[]
|
135
|
-
debug("invoking webserver with: " + Arrays.deepToString(
|
136
|
-
main.invoke(null, new Object[] {
|
154
|
+
Method main = klass.getDeclaredMethod("main", new Class[] { String[].class });
|
155
|
+
String[] newArgs = launchWebServerArguments(props);
|
156
|
+
debug("invoking webserver with: " + Arrays.deepToString(newArgs));
|
157
|
+
main.invoke(null, new Object[] { newArgs });
|
158
|
+
|
159
|
+
// the following code is specific to winstone. but a whole winstone module like the jetty module seemed
|
160
|
+
// excessive. if running under jetty (or anything other than wintstone) this will effectively do nothing.
|
161
|
+
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
162
|
+
for (Thread thread : threads) {
|
163
|
+
String name = thread.getName();
|
164
|
+
if (name.startsWith("LauncherControlThread")) {
|
165
|
+
debug("joining thread: " + name);
|
166
|
+
thread.join();
|
167
|
+
}
|
168
|
+
}
|
137
169
|
}
|
138
170
|
|
139
|
-
private String[]
|
140
|
-
String[]
|
171
|
+
private String[] launchWebServerArguments(Properties props) {
|
172
|
+
String[] newArgs = args;
|
141
173
|
|
142
174
|
if (props.getProperty("args") != null) {
|
143
175
|
String[] insertArgs = props.getProperty("args").split(",");
|
144
|
-
|
176
|
+
newArgs = new String[args.length + insertArgs.length];
|
145
177
|
for (int i = 0; i < insertArgs.length; i++) {
|
146
|
-
|
178
|
+
newArgs[i] = props.getProperty(insertArgs[i], "");
|
147
179
|
}
|
148
|
-
System.arraycopy(args, 0,
|
180
|
+
System.arraycopy(args, 0, newArgs, insertArgs.length, args.length);
|
149
181
|
}
|
150
182
|
|
151
|
-
return
|
183
|
+
return newArgs;
|
152
184
|
}
|
153
185
|
|
154
|
-
|
155
|
-
|
156
|
-
|
186
|
+
// JarMain overrides to make WarMain "launchable"
|
187
|
+
// e.g. java -jar rails.war -S rake db:migrate
|
188
|
+
|
189
|
+
@Override
|
190
|
+
protected String getExtractEntryPath(final JarEntry entry) {
|
191
|
+
final String name = entry.getName();
|
192
|
+
final String start = "WEB-INF";
|
193
|
+
if ( name.startsWith(start) ) {
|
194
|
+
// WEB-INF/app/controllers/application_controller.rb ->
|
195
|
+
// app/controllers/application_controller.rb
|
196
|
+
return name.substring(start.length());
|
197
|
+
}
|
198
|
+
if ( name.indexOf('/') == -1 ) {
|
199
|
+
// 404.html -> public/404.html
|
200
|
+
return "/public/" + name;
|
201
|
+
}
|
202
|
+
return "/" + name;
|
157
203
|
}
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
204
|
+
|
205
|
+
@Override
|
206
|
+
protected URL extractEntry(final JarEntry entry, final String path) throws Exception {
|
207
|
+
// always extract but only return class-path entry URLs :
|
208
|
+
final URL entryURL = super.extractEntry(entry, path);
|
209
|
+
return path.endsWith(".jar") ? entryURL : null;
|
210
|
+
}
|
211
|
+
|
212
|
+
@Override
|
213
|
+
protected int launchJRuby(final URL[] jars) throws Exception {
|
214
|
+
final Object scriptingContainer = newScriptingContainer(jars);
|
215
|
+
|
216
|
+
invokeMethod(scriptingContainer, "setArgv", (Object) executableArgv);
|
217
|
+
//invokeMethod(scriptingContainer, "setHomeDirectory", "classpath:/META-INF/jruby.home");
|
218
|
+
invokeMethod(scriptingContainer, "setCurrentDirectory", extractRoot.getAbsolutePath());
|
219
|
+
//invokeMethod(scriptingContainer, "runScriptlet", "ENV.clear");
|
220
|
+
//invokeMethod(scriptingContainer, "runScriptlet", "ENV['PATH']=''"); // bundler 1.1.x
|
221
|
+
|
222
|
+
final Object provider = invokeMethod(scriptingContainer, "getProvider");
|
223
|
+
final Object rubyInstanceConfig = invokeMethod(provider, "getRubyInstanceConfig");
|
224
|
+
|
225
|
+
invokeMethod(rubyInstanceConfig, "setUpdateNativeENVEnabled", new Class[] { Boolean.TYPE }, false);
|
226
|
+
|
227
|
+
final String executablePath = locateExecutable(scriptingContainer);
|
228
|
+
if ( executablePath == null ) {
|
229
|
+
throw new IllegalStateException("failed to locate gem executable: '" + executable + "'");
|
230
|
+
}
|
231
|
+
invokeMethod(scriptingContainer, "setScriptFilename", executablePath);
|
232
|
+
|
233
|
+
invokeMethod(rubyInstanceConfig, "processArguments", (Object) arguments);
|
234
|
+
|
235
|
+
Object runtime = invokeMethod(scriptingContainer, "getRuntime");
|
236
|
+
Object executableInput =
|
237
|
+
new SequenceInputStream(new ByteArrayInputStream(executableScriptEnvPrefix().getBytes()),
|
238
|
+
(InputStream) invokeMethod(rubyInstanceConfig, "getScriptSource"));
|
239
|
+
|
240
|
+
debug("invoking " + executablePath + " with: " + Arrays.toString(executableArgv));
|
241
|
+
Object outcome = invokeMethod(runtime, "runFromMain",
|
242
|
+
new Class[] { InputStream.class, String.class },
|
243
|
+
executableInput, executablePath
|
244
|
+
);
|
245
|
+
return ( outcome instanceof Number ) ? ( (Number) outcome ).intValue() : 0;
|
246
|
+
}
|
247
|
+
|
248
|
+
protected String locateExecutable(final Object scriptingContainer) throws Exception {
|
249
|
+
if ( executable == null ) {
|
250
|
+
throw new IllegalStateException("no executable");
|
251
|
+
}
|
252
|
+
final File exec = new File(extractRoot, executable);
|
253
|
+
if ( exec.exists() ) {
|
254
|
+
return exec.getAbsolutePath();
|
162
255
|
}
|
256
|
+
else {
|
257
|
+
final String script = locateExecutableScript(executable);
|
258
|
+
return (String) invokeMethod(scriptingContainer, "runScriptlet", script);
|
259
|
+
}
|
260
|
+
}
|
261
|
+
protected String executableScriptEnvPrefix() {
|
262
|
+
final String gemsDir = new File(extractRoot, "gems").getAbsolutePath();
|
263
|
+
final String gemfile = new File(extractRoot, "Gemfile").getAbsolutePath();
|
264
|
+
debug("setting GEM_HOME to " + gemsDir);
|
265
|
+
debug("... and BUNDLE_GEMFILE to " + gemfile);
|
266
|
+
return "ENV['GEM_HOME'] ||= ENV['GEM_PATH'] = '"+ gemsDir +"' \n" +
|
267
|
+
"ENV['BUNDLE_GEMFILE'] ||= '"+ gemfile +"' \n" +
|
268
|
+
"require 'META-INF/init.rb' \n";
|
163
269
|
}
|
164
270
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
271
|
+
protected String locateExecutableScript(final String executable) {
|
272
|
+
return executableScriptEnvPrefix() +
|
273
|
+
"begin\n" +
|
274
|
+
// locate the executable within gemspecs :
|
275
|
+
" require 'rubygems' \n" +
|
276
|
+
" begin\n" +
|
277
|
+
// add bundler gems to load path:
|
278
|
+
" require 'bundler' \n" +
|
279
|
+
// TODO: environment from web.xml. Any others?
|
280
|
+
" Bundler.setup(:default, *ENV.values_at('RACK_ENV', 'RAILS_ENV').compact)\n" +
|
281
|
+
" rescue LoadError\n" +
|
282
|
+
// bundler not used
|
283
|
+
" end\n" +
|
284
|
+
" exec = '"+ executable +"' \n" +
|
285
|
+
" spec = Gem::Specification.find { |s| s.executables.include?(exec) } \n" +
|
286
|
+
" spec ? spec.bin_file(exec) : nil \n" +
|
287
|
+
// returns the full path to the executable
|
288
|
+
"rescue SystemExit => e\n" +
|
289
|
+
" e.status\n" +
|
290
|
+
"end";
|
291
|
+
}
|
292
|
+
|
293
|
+
@Override
|
294
|
+
protected int start() throws Exception {
|
295
|
+
if ( executable == null ) {
|
296
|
+
try {
|
297
|
+
URL server = extractWebserver();
|
298
|
+
launchWebServer(server);
|
299
|
+
}
|
300
|
+
catch (FileNotFoundException e) {
|
301
|
+
if ( e.getMessage().indexOf("WEB-INF/webserver.jar") > -1 ) {
|
302
|
+
System.out.println("specify the -S argument followed by the bin file to run e.g. `java -jar rails.war -S rake -T` ...");
|
303
|
+
System.out.println("(or if you'd like your .war file to start a web server package it using `warbler executable war`)");
|
304
|
+
}
|
305
|
+
throw e;
|
170
306
|
}
|
307
|
+
return 0;
|
308
|
+
}
|
309
|
+
else {
|
310
|
+
return super.start();
|
171
311
|
}
|
172
|
-
f.delete();
|
173
312
|
}
|
174
313
|
|
314
|
+
@Override
|
175
315
|
public void run() {
|
176
|
-
|
316
|
+
super.run();
|
317
|
+
if ( webroot != null ) delete(webroot.getParentFile());
|
177
318
|
}
|
178
319
|
|
179
320
|
public static void main(String[] args) {
|
180
|
-
|
181
|
-
new WarMain(args).start();
|
182
|
-
} catch (Exception e) {
|
183
|
-
System.err.println("error: " + e.toString());
|
184
|
-
if (isDebug()) {
|
185
|
-
e.printStackTrace();
|
186
|
-
}
|
187
|
-
System.exit(1);
|
188
|
-
}
|
321
|
+
doStart(new WarMain(args));
|
189
322
|
}
|
190
323
|
|
191
|
-
private static boolean isDebug() {
|
192
|
-
return System.getProperty("warbler.debug") != null;
|
193
|
-
}
|
194
324
|
}
|
195
|
-
|
data/ext/WarblerJar.java
CHANGED
@@ -168,11 +168,21 @@ public class WarblerJar {
|
|
168
168
|
return entryInJar(stream, entry);
|
169
169
|
}
|
170
170
|
|
171
|
+
private static String trimTrailingSlashes(String path) {
|
172
|
+
if (path.endsWith("/")) {
|
173
|
+
return path.substring(0, path.length() - 1);
|
174
|
+
} else {
|
175
|
+
return path;
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
171
179
|
private static InputStream entryInJar(InputStream jar, String entry) throws IOException {
|
180
|
+
entry = trimTrailingSlashes(entry);
|
181
|
+
|
172
182
|
ZipInputStream jstream = new ZipInputStream(jar);
|
173
183
|
ZipEntry zentry = null;
|
174
184
|
while ((zentry = jstream.getNextEntry()) != null) {
|
175
|
-
if (zentry.getName().equals(entry)) {
|
185
|
+
if (trimTrailingSlashes(zentry.getName()).equals(entry)) {
|
176
186
|
return jstream;
|
177
187
|
}
|
178
188
|
jstream.closeEntry();
|
data/lib/warbler.rb
CHANGED
@@ -9,7 +9,8 @@
|
|
9
9
|
# your Ruby applications into .jar or .war files.
|
10
10
|
module Warbler
|
11
11
|
WARBLER_HOME = File.expand_path(File.dirname(__FILE__) + '/..') unless defined?(WARBLER_HOME)
|
12
|
-
|
12
|
+
WARBLER_JAR = "#{WARBLER_HOME}/lib/warbler_jar.jar" unless defined?(WARBLER_JAR)
|
13
|
+
|
13
14
|
class << self
|
14
15
|
# An instance of Warbler::Application used by the +warble+ command.
|
15
16
|
attr_accessor :application
|
data/lib/warbler/application.rb
CHANGED
@@ -37,9 +37,12 @@ class Warbler::Application < Rake::Application
|
|
37
37
|
desc "Feature: package gem repository inside a jar"
|
38
38
|
task :gemjar => "#{wt.name}:gemjar"
|
39
39
|
|
40
|
-
desc "Feature: make an executable archive"
|
40
|
+
desc "Feature: make an executable archive (runnable + an embedded web server)"
|
41
41
|
task :executable => "#{wt.name}:executable"
|
42
42
|
|
43
|
+
desc "Feature: make a runnable archive (e.g. java -jar rails.war -S rake db:migrate)"
|
44
|
+
task :runnable => "#{wt.name}:runnable"
|
45
|
+
|
43
46
|
desc "Feature: precompile all Ruby files"
|
44
47
|
task :compiled => "#{wt.name}:compiled"
|
45
48
|
|
data/lib/warbler/config.rb
CHANGED
@@ -14,7 +14,7 @@ module Warbler
|
|
14
14
|
class Config
|
15
15
|
include RakeHelper
|
16
16
|
|
17
|
-
TOP_DIRS = %w(app config lib log vendor)
|
17
|
+
TOP_DIRS = %w(app db config lib log script vendor)
|
18
18
|
FILE = "config/warble.rb"
|
19
19
|
BUILD_GEMS = %w(warbler rake rcov)
|
20
20
|
|
@@ -96,7 +96,7 @@ module Warbler
|
|
96
96
|
attr_accessor :bundler
|
97
97
|
|
98
98
|
# An array of Bundler groups to avoid including in the war file.
|
99
|
-
# Defaults to ["development", "test"].
|
99
|
+
# Defaults to ["development", "test", "assets"].
|
100
100
|
attr_accessor :bundle_without
|
101
101
|
|
102
102
|
# Path to the pre-bundled gem directory inside the war file. Default is '/WEB-INF/gems'.
|
@@ -115,6 +115,12 @@ module Warbler
|
|
115
115
|
# If the filename ends in .erb the file will be expanded the same way web.xml.erb is; see below.
|
116
116
|
attr_accessor :init_contents
|
117
117
|
|
118
|
+
# Override GEM_HOME environment variable at runtime. When false, gems in
|
119
|
+
# GEM_HOME will be loaded in preference to those packaged within the jar
|
120
|
+
# file. When true, only gems packaged in the jar file will be loaded.
|
121
|
+
# Defaults to false
|
122
|
+
attr_accessor :override_gem_home
|
123
|
+
|
118
124
|
# Extra configuration for web.xml. Controls how the dynamically-generated web.xml
|
119
125
|
# file is generated.
|
120
126
|
#
|
@@ -158,7 +164,7 @@ module Warbler
|
|
158
164
|
@warbler_templates = "#{WARBLER_HOME}/lib/warbler/templates"
|
159
165
|
@features = Set.new
|
160
166
|
@dirs = TOP_DIRS.select {|d| File.directory?(d)}
|
161
|
-
@includes = FileList[]
|
167
|
+
@includes = FileList['*file'] # [r/R]akefile gets included
|
162
168
|
@excludes = FileList[]
|
163
169
|
@java_libs = FileList[]
|
164
170
|
@java_classes = FileList[]
|
@@ -172,6 +178,7 @@ module Warbler
|
|
172
178
|
@webinf_files = FileList[]
|
173
179
|
@init_filename = 'META-INF/init.rb'
|
174
180
|
@init_contents = ["#{@warbler_templates}/config.erb"]
|
181
|
+
@override_gem_home = false
|
175
182
|
|
176
183
|
before_configure
|
177
184
|
yield self if block_given?
|
@@ -180,6 +187,7 @@ module Warbler
|
|
180
187
|
@compiled_ruby_files ||= FileList[*@dirs.map {|d| "#{d}/**/*.rb"}]
|
181
188
|
|
182
189
|
@excludes += ["tmp/war", "tmp/war/**/*"] if File.directory?("tmp/war")
|
190
|
+
@excludes += ["tmp/cache/**/*"] if File.directory?("tmp/cache")
|
183
191
|
@excludes += warbler_vendor_excludes(warbler_home)
|
184
192
|
@excludes += FileList["**/*.log"] if @exclude_logs
|
185
193
|
end
|
@@ -199,6 +207,9 @@ module Warbler
|
|
199
207
|
task "executable" do
|
200
208
|
self.features << "executable"
|
201
209
|
end
|
210
|
+
task "runnable" do
|
211
|
+
self.features << "runnable"
|
212
|
+
end
|
202
213
|
end
|
203
214
|
|
204
215
|
# Deprecated
|
data/lib/warbler/jar.rb
CHANGED
@@ -44,8 +44,13 @@ module Warbler
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def run_javac(config, compiled_ruby_files)
|
47
|
+
if config.webxml && config.webxml.context_params.has_key?('jruby.compat.version')
|
48
|
+
compat_version = "--#{config.webxml.jruby.compat.version}"
|
49
|
+
else
|
50
|
+
compat_version = ''
|
51
|
+
end
|
47
52
|
# Need to use the version of JRuby in the application to compile it
|
48
|
-
%x{java -classpath #{config.java_libs.join(File::PATH_SEPARATOR)} org.jruby.Main -S jrubyc \"#{compiled_ruby_files.join('" "')}\"}
|
53
|
+
%x{java -classpath #{config.java_libs.join(File::PATH_SEPARATOR)} org.jruby.Main #{compat_version} -S jrubyc \"#{compiled_ruby_files.join('" "')}\"}
|
49
54
|
end
|
50
55
|
|
51
56
|
def replace_compiled_ruby_files(config, compiled_ruby_files)
|
@@ -54,7 +59,7 @@ module Warbler
|
|
54
59
|
config.excludes += compiled_ruby_files
|
55
60
|
|
56
61
|
compiled_ruby_files.each do |ruby_source|
|
57
|
-
files[apply_pathmaps(config, ruby_source, :application)] = StringIO.new("
|
62
|
+
files[apply_pathmaps(config, ruby_source, :application)] = StringIO.new("load __FILE__.sub(/\.rb$/, '.class')")
|
58
63
|
end
|
59
64
|
end
|
60
65
|
|
@@ -81,6 +86,9 @@ module Warbler
|
|
81
86
|
rm_f path
|
82
87
|
ensure_directory_entries
|
83
88
|
puts "Creating #{path}"
|
89
|
+
if Warbler::Config === config_or_path
|
90
|
+
@files.delete("#{config_or_path.jar_name}/#{path}")
|
91
|
+
end
|
84
92
|
create_jar path, @files
|
85
93
|
end
|
86
94
|
|