jarbler 0.3.2 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +11 -10
- data/lib/jarbler/JarMain.java +68 -20
- data/lib/jarbler/builder.rb +83 -32
- data/lib/jarbler/config.rb +10 -9
- data/lib/jarbler/version.rb +2 -2
- data/log/.keep +0 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b0f184ae1d09ac0464ed7c607600571e77873ae91a1aa2c20578856cd2b8404
|
4
|
+
data.tar.gz: 0dce28c9d7e4856d5903da84f8ea4f5ec5f173931fe4fca6ec5e8e849bbcbc4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b4383469571b3ce72c7e97123f8a8a0b25834848970921ae84dd445f3ea9268fec77193b796dddd2444831d5854e477d13d912de9d962fea3bcdd74ecb9d56d
|
7
|
+
data.tar.gz: dfcfdd76de3397adabb0e8677c09dedc112486387addeca59f8b85b50b40f8d7230c337b61c191f2d2752eb1cf9514011905579818add6665cce66dc38db0b66
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.3.5] - 2025-03-22
|
4
|
+
|
5
|
+
- new config attribute "config.compile_java_version" allows control of setting for "javac -source and -target" for AOT compilation
|
6
|
+
- fix typo with smart quotes in config.rb
|
7
|
+
|
8
|
+
## [0.3.4] - 2025-03-07
|
9
|
+
|
10
|
+
- Warning if Ruby-specific environment variables (GEM_HOME etc.) are set which may cause malfunction of app in jar file
|
11
|
+
- Accept jar file locations with blanks in the path, especially for Windows
|
12
|
+
- Setting `compile_ruby_files=true` compiles only .rb file of the application, but does not compile the .rb files in Gems.<br/>
|
13
|
+
Compiling the Gems also remains an open task.
|
14
|
+
- Bugfix: Accept spaces in the path to the jar file, especially for Windows
|
15
|
+
|
3
16
|
## [0.3.1] - 2024-07-02
|
4
17
|
|
5
18
|
- Use file .ruby-version to define the JRuby version for the jar file only if .ruby-version contains a valid jRuby version
|
data/README.md
CHANGED
@@ -53,16 +53,17 @@ To create a template config file with information about all the supported config
|
|
53
53
|
The default configuration is focused on Ruby on Rails applications.<br>
|
54
54
|
|
55
55
|
### Configuration options
|
56
|
-
| Option | Default value | Description
|
57
|
-
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
| Option | Default value | Description |
|
57
|
+
|-------------------------|------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
58
|
+
| compile_java_version | none | Java version the compiled .class files should be compatible with. Controls the target and source version of the Java compiler if compile_ruby_files=true (javac -source and -target). E.g. "1.8" for Java 8. If not set then it generates the class file version according to your current Java version. |
|
59
|
+
| compile_ruby_files | false | Ahead of time compilation of all .rb files of the application to .class files. Only the .class files are stored in the jar file. The Gem dependencies are not compiled. Requires JRuby as Ruby environment at compile time. |
|
60
|
+
| executable | "bin/rails" | The ruby start file to run at execution of jar file. File extension .class is used automatically if start file is .rb and AOT compilation is used. |
|
61
|
+
| executable_params | ["server", "-e", "production", "-p", "8080"] | Command line parameters to be used for the ruby executable |
|
62
|
+
| excludes_from_compile | [] | The files and dirs of the project to exclude from the compilation of .rb files. Paths specifies the location in the jar file (e.g. ["app_root/file.rb"] ) |
|
63
|
+
| excludes | ["tmp/cache", "tmp/pids", ...] (see generated template file for whole content) | The files and dirs of the project to exclude from the include option |
|
64
|
+
| includes | ["app", "bin", "config", ...] (see generated template file for whole content) | The files and dirs of the project to include in the jar file |
|
65
|
+
| jar_name | < Name of project dir >.jar | The name of the generated jar file |
|
66
|
+
| jruby_version | A valid JRuby version from file '.ruby-version' or the current most recent version of the Gem 'jruby-jars' | The version of the JRuby runtime to use |
|
66
67
|
|
67
68
|
|
68
69
|
## Troubleshooting
|
data/lib/jarbler/JarMain.java
CHANGED
@@ -10,6 +10,7 @@ import java.util.jar.JarFile;
|
|
10
10
|
import java.util.jar.JarInputStream;
|
11
11
|
import java.util.jar.JarOutputStream;
|
12
12
|
import java.util.ArrayList;
|
13
|
+
import java.util.Arrays;
|
13
14
|
import java.util.Properties;
|
14
15
|
import java.util.zip.ZipEntry;
|
15
16
|
import java.util.zip.ZipInputStream;
|
@@ -42,26 +43,28 @@ class JarMain {
|
|
42
43
|
debug(" - " + arg);
|
43
44
|
}
|
44
45
|
}
|
46
|
+
|
45
47
|
// create a new folder in temp directory
|
46
48
|
File newFolder = new File(System.getProperty("java.io.tmpdir") + File.separator + UUID.randomUUID().toString());
|
47
49
|
newFolder.mkdir();
|
50
|
+
|
48
51
|
try {
|
49
|
-
// Get the path of the jar file
|
50
|
-
String jarPath = JarMain.class.getProtectionDomain().getCodeSource().getLocation().getPath();
|
51
|
-
|
52
|
-
// remove the leading slash if path is a windows path
|
53
|
-
String os = System.getProperty("os.name").toLowerCase();
|
54
|
-
boolean isWindows = os.contains("windows");
|
55
|
-
if (os.contains("windows") && jarPath.startsWith("/") && jarPath.indexOf(':') != -1) {
|
56
|
-
jarPath = jarPath.substring(1); // remove the leading slash
|
57
|
-
}
|
58
52
|
|
59
|
-
//
|
60
|
-
|
53
|
+
// Ensure that environment does not inject external dependencies
|
54
|
+
checkEnvForToxicEntries();
|
55
|
+
|
56
|
+
// Get the path of the jar file with valid characters for spaces etc., especially for Windows
|
57
|
+
URL jarPathUrl = JarMain.class.getProtectionDomain().getCodeSource().getLocation();
|
58
|
+
|
59
|
+
// Convert the URL to a URI, then to a File
|
60
|
+
File jarFile = new File(jarPathUrl.toURI());
|
61
|
+
|
62
|
+
// Get the absolute path of the file
|
63
|
+
String jarPath = jarFile.getAbsolutePath();
|
61
64
|
|
62
65
|
// extract the jarFile by unzipping it (not using the jar utility which may not be available)
|
63
|
-
System.out.println("Extracting files from "+
|
64
|
-
unzip(
|
66
|
+
System.out.println("Extracting files from "+jarPath+" to "+ newFolder.getAbsolutePath());
|
67
|
+
unzip(jarPath, newFolder.getAbsolutePath());
|
65
68
|
|
66
69
|
String app_root = newFolder.getAbsolutePath()+File.separator+"app_root";
|
67
70
|
|
@@ -87,8 +90,9 @@ class JarMain {
|
|
87
90
|
|
88
91
|
Properties prop = new Properties();
|
89
92
|
prop.load(new FileInputStream(newFolder.getAbsolutePath()+File.separator+"jarbler.properties"));
|
90
|
-
executable
|
91
|
-
executable_params
|
93
|
+
executable = prop.getProperty("jarbler.executable");
|
94
|
+
executable_params = prop.getProperty("jarbler.executable_params");
|
95
|
+
String gem_home_suffix = prop.getProperty("jarbler.gem_home_suffix");
|
92
96
|
|
93
97
|
Boolean compile_ruby_files = Boolean.parseBoolean(prop.getProperty("jarbler.compile_ruby_files", "false"));
|
94
98
|
if (compile_ruby_files) {
|
@@ -102,8 +106,11 @@ class JarMain {
|
|
102
106
|
throw new RuntimeException("Property 'executable' definition missing in jarbler.properties");
|
103
107
|
}
|
104
108
|
|
109
|
+
// single path to the gems directory
|
110
|
+
String gem_home = newFolder.getAbsolutePath()+File.separator+"gems";
|
111
|
+
|
105
112
|
// create the bundle config file with the path of the gems
|
106
|
-
create_bundle_config(app_root,
|
113
|
+
create_bundle_config(app_root, gem_home);
|
107
114
|
|
108
115
|
// Load the Jar file
|
109
116
|
URLClassLoader classLoader = new URLClassLoader(new URL[]{
|
@@ -112,7 +119,6 @@ class JarMain {
|
|
112
119
|
//new URL("file:/" + jrubyCoreFile.getAbsolutePath()),
|
113
120
|
//new URL("file:/" + jrubyStdlibFile.getAbsolutePath())
|
114
121
|
});
|
115
|
-
|
116
122
|
// Load the class
|
117
123
|
Class<?> clazz = classLoader.loadClass("org.jruby.Main");
|
118
124
|
|
@@ -139,16 +145,24 @@ class JarMain {
|
|
139
145
|
}
|
140
146
|
}
|
141
147
|
|
148
|
+
debug("JRuby set property 'user.dir' to '" + app_root + "'");
|
149
|
+
System.setProperty("user.dir", app_root);
|
150
|
+
|
151
|
+
// GEM_HOME not explicitely set because this is done by Bundle.setup based on the .bundle/config file
|
152
|
+
// Setting GEM_HOME explicitely may cause problems with the JRuby runtime (Gem::GemNotFoundException: can't find gem bundler (= 2.6.3) with executable bundle)
|
153
|
+
//String full_gem_home = gem_home + File.separator + gem_home_suffix.replace("/", File.separator);
|
154
|
+
//debug("JRuby set property 'jruby.gem.home' to '" + full_gem_home + "'");
|
155
|
+
//System.setProperty("jruby.gem.home", full_gem_home);
|
156
|
+
|
142
157
|
debug("JRuby program starts with the following arguments: ");
|
143
158
|
for (String arg : mainArgs) {
|
144
159
|
debug(" - " + arg);
|
145
160
|
}
|
146
161
|
|
147
|
-
debug("JRuby set property 'user.dir' to '" + app_root + "'");
|
148
|
-
System.setProperty("user.dir", app_root);
|
149
162
|
// call the method org.jruby.Main.main
|
150
163
|
debug("Calling org.jruby.Main.main with: "+ mainArgs);
|
151
164
|
mainMethod.invoke(null, (Object)mainArgs.toArray(new String[mainArgs.size()]));
|
165
|
+
// TODO: evaluate return value
|
152
166
|
} catch (Exception e) {
|
153
167
|
e.printStackTrace();
|
154
168
|
} finally {
|
@@ -228,7 +242,7 @@ class JarMain {
|
|
228
242
|
|
229
243
|
private static void debug(String msg) {
|
230
244
|
if (System.getenv("DEBUG") != null) {
|
231
|
-
System.
|
245
|
+
System.err.println(msg);
|
232
246
|
}
|
233
247
|
}
|
234
248
|
|
@@ -269,4 +283,38 @@ class JarMain {
|
|
269
283
|
}
|
270
284
|
return jarFileName;
|
271
285
|
}
|
286
|
+
|
287
|
+
/**
|
288
|
+
* Check environment for entries that may inluence execution of Ruby code.
|
289
|
+
* @param errorSummary The current error summary
|
290
|
+
*/
|
291
|
+
private static void checkEnvForToxicEntries(){
|
292
|
+
StringBuilder errorSummary = new StringBuilder("");
|
293
|
+
String toxicEntries[] = {
|
294
|
+
"BUNDLE_BIN_PATH",
|
295
|
+
"BUNDLE_GEMFILE",
|
296
|
+
"BUNDLER_SETUP",
|
297
|
+
"BUNDLER_VERSION",
|
298
|
+
"GEM_HOME",
|
299
|
+
"GEM_PATH",
|
300
|
+
"RUBYLIB",
|
301
|
+
"RUBYOPT",
|
302
|
+
"RUBYPATH",
|
303
|
+
"RUBYSHELL"
|
304
|
+
};
|
305
|
+
|
306
|
+
Arrays.stream(toxicEntries).forEach(entry -> {
|
307
|
+
String envVal = System.getenv(entry);
|
308
|
+
if (envVal != null) {
|
309
|
+
errorSummary.append("Found environment variable '"+entry+"' with value '"+envVal+"'\n");
|
310
|
+
debug("Possibly toxic environment variable found: '"+entry+"'! Remove it from environment before execution of jar file if it causes errors.");
|
311
|
+
}
|
312
|
+
});
|
313
|
+
|
314
|
+
if (!errorSummary.toString().isEmpty()){
|
315
|
+
System.err.println("The follwing environment variables may influence the execution of the packaged Ruby code.");
|
316
|
+
System.err.println("Please remove this environment entries before the execution of the jar file if they cause errors.");
|
317
|
+
System.err.println(errorSummary);
|
318
|
+
}
|
319
|
+
}
|
272
320
|
}
|
data/lib/jarbler/builder.rb
CHANGED
@@ -4,6 +4,7 @@ require 'bundler'
|
|
4
4
|
require 'find'
|
5
5
|
require 'fileutils'
|
6
6
|
require 'yaml'
|
7
|
+
require 'open3'
|
7
8
|
|
8
9
|
module Jarbler
|
9
10
|
class Builder
|
@@ -18,8 +19,12 @@ module Jarbler
|
|
18
19
|
app_root = Dir.pwd
|
19
20
|
debug "Project dir: #{app_root}"
|
20
21
|
|
22
|
+
source_and_target = if config.compile_java_version
|
23
|
+
"-source #{config.compile_java_version} -target #{config.compile_java_version}"
|
24
|
+
end
|
25
|
+
|
21
26
|
ruby_minor_version = copy_jruby_jars_to_staging(staging_dir) # Copy the jruby jars to the staging directory
|
22
|
-
exec_command "javac -nowarn -Xlint:deprecation
|
27
|
+
exec_command "javac -nowarn -Xlint:deprecation #{source_and_target} -d #{staging_dir} #{__dir__}/JarMain.java" # Compile the Java files
|
23
28
|
|
24
29
|
# Copy the application project to the staging directory
|
25
30
|
FileUtils.mkdir_p("#{staging_dir}/app_root")
|
@@ -50,6 +55,7 @@ module Jarbler
|
|
50
55
|
end
|
51
56
|
file.write("jarbler.executable_params=#{java_executable_params.strip}\n")
|
52
57
|
file.write("jarbler.compile_ruby_files=#{config.compile_ruby_files}\n")
|
58
|
+
file.write("jarbler.gem_home_suffix=jruby/#{ruby_minor_version}\n") # Extension after BUNDLE_PATH for local Gems
|
53
59
|
end
|
54
60
|
|
55
61
|
# remove files and directories from excludes, if they exist (after copying the rails project and the gems)
|
@@ -86,30 +92,20 @@ module Jarbler
|
|
86
92
|
|
87
93
|
private
|
88
94
|
|
89
|
-
|
90
|
-
# Check if there is an additional local bundle path in .bundle/config
|
91
|
-
# @param rails_root [String] the rails root directory
|
92
|
-
# @return [String] the local bundle path or nil if not configured
|
93
|
-
def bundle_config_bundle_path(rails_root)
|
94
|
-
bundle_path = nil # default
|
95
|
-
if File.exist?("#{rails_root}/.bundle/config")
|
96
|
-
bundle_config = YAML.load_file("#{rails_root}/.bundle/config")
|
97
|
-
if bundle_config && bundle_config['BUNDLE_PATH']
|
98
|
-
bundle_path = "#{rails_root}/#{bundle_config['BUNDLE_PATH']}"
|
99
|
-
debug "Local Gem path configured in #{rails_root}/.bundle/config: #{bundle_path}"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
bundle_path
|
103
|
-
end
|
104
|
-
|
105
95
|
# Copy the needed Gems to the staging directory
|
106
96
|
# @param staging_dir [String] the staging directory
|
107
97
|
# @param ruby_minor_version [String] the corresponding ruby minor version of the jruby jars version
|
108
98
|
# @return [void]
|
109
99
|
def copy_needed_gems_to_staging(staging_dir, ruby_minor_version)
|
110
100
|
gem_target_location = "#{staging_dir}/gems/jruby/#{ruby_minor_version}"
|
101
|
+
FileUtils.mkdir_p("#{gem_target_location}/bin")
|
102
|
+
FileUtils.mkdir_p("#{gem_target_location}/build_info")
|
103
|
+
FileUtils.mkdir_p("#{gem_target_location}/cache")
|
104
|
+
FileUtils.mkdir_p("#{gem_target_location}/doc")
|
105
|
+
FileUtils.mkdir_p("#{gem_target_location}/extensions")
|
111
106
|
FileUtils.mkdir_p("#{gem_target_location}/gems")
|
112
107
|
FileUtils.mkdir_p("#{gem_target_location}/specifications")
|
108
|
+
FileUtils.mkdir_p("#{gem_target_location}/bundler/bin")
|
113
109
|
FileUtils.mkdir_p("#{gem_target_location}/bundler/gems")
|
114
110
|
|
115
111
|
needed_gems = gem_dependencies # get the full names of the dependencies
|
@@ -123,21 +119,34 @@ module Jarbler
|
|
123
119
|
if spec.source.is_a?(Bundler::Source::Git)
|
124
120
|
# Copy the Gem from bundler/gems including the gemspec
|
125
121
|
file_utils_copy(spec.gem_dir, "#{gem_target_location}/bundler/gems")
|
122
|
+
spec.executables.each do |executable|
|
123
|
+
file_utils_copy("#{spec.bin_dir}/#{executable}", "#{gem_target_location}/bundler/bin")
|
124
|
+
end
|
126
125
|
else # Gem is from rubygems
|
126
|
+
# TODO: Gemfile could request a different version of default gem compared to the one jruby jars
|
127
|
+
# Should the default gems are also copied to the staging directory?
|
127
128
|
unless spec.default_gem? # Do not copy default gems, because they are already included in the jruby jars standard library
|
128
129
|
# copy the Gem and gemspec separately
|
129
130
|
file_utils_copy(spec.gem_dir, "#{gem_target_location}/gems")
|
130
|
-
|
131
|
+
# spec.loaded_from contains the path to the gemspec file including the path prefix "default/" for default gems
|
132
|
+
file_utils_copy(spec.loaded_from, "#{gem_target_location}/specifications")
|
133
|
+
spec.executables.each do |executable|
|
134
|
+
file_utils_copy("#{spec.bin_dir}/#{executable}", "#{gem_target_location}/bin")
|
135
|
+
end
|
131
136
|
end
|
132
137
|
end
|
133
138
|
end
|
139
|
+
rescue Exception => e
|
140
|
+
debug("Builder.copy_needed_gems_to_staging: Failed with staging dir = '#{staging_dir}' and ruby minor version = #{ruby_minor_version} with #{e.class}\n#{e.message}")
|
141
|
+
raise
|
134
142
|
end
|
135
143
|
|
136
144
|
# Read the default/production dependencies from Gemfile.lock and Gemfile
|
137
145
|
# @return [Array] Array with Hashes containing: name, version, full_name
|
138
146
|
def gem_dependencies
|
139
147
|
needed_gems = []
|
140
|
-
|
148
|
+
lockfile_parser = Bundler::LockfileParser.new(Bundler.read_file(Bundler.default_lockfile))
|
149
|
+
lockfile_specs = lockfile_parser.specs
|
141
150
|
|
142
151
|
Bundler.setup # Load Gems specified in Gemfile, ensure that Gem path also includes the Gems loaded into bundler dir
|
143
152
|
# filter Gems needed for production
|
@@ -156,10 +165,18 @@ module Jarbler
|
|
156
165
|
debug "Direct Gem dependency: #{lockfile_spec.full_name}"
|
157
166
|
add_indirect_dependencies(lockfile_specs, lockfile_spec, needed_gems)
|
158
167
|
else
|
159
|
-
|
168
|
+
if gemfile_spec.name == 'bundler'
|
169
|
+
debug "Gem bundler found in Gemfile.lock but not in specs, use version #{Bundler::VERSION}"
|
170
|
+
needed_gems << { full_name: "bundler-#{lockfile_parser.bundler_version}", name: 'bundler', version: lockfile_parser.bundler_version }
|
171
|
+
else
|
172
|
+
debug "Gem #{gemfile_spec.name} not found in specs: in Gemfile.lock"
|
173
|
+
end
|
160
174
|
end
|
161
175
|
end
|
162
|
-
needed_gems.uniq.sort{|a,b| a[:full_name] <=> b[:full_name]}
|
176
|
+
needed_gems.uniq.sort{|a,b| a[:full_name] <=> b[:full_name]} # full_name also contains version
|
177
|
+
rescue Exception => e
|
178
|
+
debug("Builder.gem_dependencies: Failed with #{e.class}\n#{e.message}")
|
179
|
+
raise
|
163
180
|
end
|
164
181
|
|
165
182
|
# recurively find all indirect dependencies
|
@@ -180,13 +197,16 @@ module Jarbler
|
|
180
197
|
debug "Gem #{lockfile_spec_dep.name} not found in Gemfile.lock"
|
181
198
|
end
|
182
199
|
end
|
200
|
+
rescue Exception => e
|
201
|
+
debug("Builder.add_indirect_dependencies: Failed with #{e.class}\n#{e.message}")
|
202
|
+
raise
|
183
203
|
end
|
184
204
|
|
185
205
|
# Output debug message if DEBUG environment variable is set
|
186
206
|
# @param [String] msg Message to output
|
187
207
|
# @return [void]
|
188
208
|
def debug(msg)
|
189
|
-
puts msg if ENV['DEBUG']
|
209
|
+
puts "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} #{msg}" if ENV['DEBUG']
|
190
210
|
end
|
191
211
|
|
192
212
|
# Get the config object
|
@@ -201,6 +221,9 @@ module Jarbler
|
|
201
221
|
debug ""
|
202
222
|
end
|
203
223
|
@config
|
224
|
+
rescue Exception => e
|
225
|
+
debug("Builder.config: Failed with #{e.class}\n#{e.message}")
|
226
|
+
raise
|
204
227
|
end
|
205
228
|
|
206
229
|
# Copy the jruby-jars to the staging directory
|
@@ -208,12 +231,26 @@ module Jarbler
|
|
208
231
|
# @return [String] the minor ruby version of the JRuby jars with patch level set to 0
|
209
232
|
def copy_jruby_jars_to_staging(staging_dir)
|
210
233
|
|
234
|
+
debug "Copying JRuby Jars to staging dir: #{staging_dir}"
|
211
235
|
# Ensure that jruby-jars gem is installed, otherwise install it. Accepts also bundler path in .bundle/config
|
212
|
-
|
213
|
-
|
236
|
+
installed = nil # ensure that installed is defined outside of the block
|
237
|
+
tries = 5
|
238
|
+
tries.times do |try|
|
239
|
+
begin
|
240
|
+
installer = Gem::DependencyInstaller.new
|
241
|
+
installed = installer.install('jruby-jars', config.jruby_version)
|
242
|
+
break # escape loop if successful
|
243
|
+
rescue Exception, RuntimeError => e
|
244
|
+
debug "Builder.copy_jruby_jars_to_staging: Failed to install jruby-jars #{try}. try with #{e.class}\n#{e.message}"
|
245
|
+
raise if try == tries - 1 # last try not successful
|
246
|
+
sleeptime = 5
|
247
|
+
debug "Builder.copy_jruby_jars_to_staging: Waiting #{sleeptime} seconds to prevent from Gem::RemoteFetcher::FetchError: IOError: closed stream"
|
248
|
+
sleep sleeptime # wait x seconds before next try
|
249
|
+
end
|
250
|
+
end
|
214
251
|
raise "jruby-jars gem not installed in version #{config.jruby_version}" if installed.empty?
|
215
252
|
|
216
|
-
jruby_jars_location = installed[0]&.full_gem_path
|
253
|
+
jruby_jars_location = installed[0]&.full_gem_path # need to be the first installed Gem
|
217
254
|
debug "JRuby jars installed at: #{jruby_jars_location}"
|
218
255
|
|
219
256
|
# Get the location of the jruby-jars gem
|
@@ -232,16 +269,24 @@ module Jarbler
|
|
232
269
|
ruby_minor_version = ruby_version.split('.')[0..1].join('.') + '.0'
|
233
270
|
debug "Corresponding Ruby minor version for JRuby (#{config.jruby_version}): #{ruby_minor_version}"
|
234
271
|
ruby_minor_version
|
272
|
+
rescue Exception => e
|
273
|
+
debug "Builder.copy_jruby_jars_to_staging: Failed to copy JRuby jars to staging dir '#{jruby_jars_location}' with #{e.class}\n#{e.message}"
|
274
|
+
debug "Stack trace of exception:\n#{e.backtrace.join("\n")}"
|
275
|
+
raise
|
235
276
|
end
|
236
277
|
|
237
278
|
# Execute the command in OS and return the output
|
238
279
|
# @param [String] command Command to execute
|
239
280
|
# @return [String] the output of the command
|
240
281
|
def exec_command(command)
|
241
|
-
|
242
|
-
|
243
|
-
debug "Command \"#{command}\" executed
|
244
|
-
|
282
|
+
debug("Execute by Open3.capture3: #{command}")
|
283
|
+
stdout, stderr, status = Open3.capture3(command)
|
284
|
+
debug "Command \"#{command}\" executed with return code #{status}!\nstdout:\n#{stdout}\n\nstderr:\n#{stderr}\n"
|
285
|
+
raise "Command \"#{command}\" failed with return code #{status}!\nstdout:\n#{stdout}\n\nstderr:\n#{stderr}\n" unless status.success?
|
286
|
+
"stdout:\n#{stdout}\nstderr:\n#{stderr}\n"
|
287
|
+
rescue Exception => e
|
288
|
+
debug "Builder.exec_command: Failed to execute command '#{command}' with #{e.class}\n#{e.message}"
|
289
|
+
raise
|
245
290
|
end
|
246
291
|
|
247
292
|
# Copy file or directory with error handling
|
@@ -254,8 +299,8 @@ module Jarbler
|
|
254
299
|
else
|
255
300
|
FileUtils.cp(source, destination)
|
256
301
|
end
|
257
|
-
rescue Exception
|
258
|
-
|
302
|
+
rescue Exception => e
|
303
|
+
debug "Builder.file_utils_copy: Failed to copy '#{source}' to '#{destination}' with #{e.class}\n#{e.message}"
|
259
304
|
raise
|
260
305
|
end
|
261
306
|
|
@@ -267,9 +312,12 @@ module Jarbler
|
|
267
312
|
# Inform if used JRuby version is different from the intended runtime JRuby version
|
268
313
|
if JRUBY_VERSION != config.jruby_version
|
269
314
|
puts "Compiling .rb files to .class is done with JRuby version #{JRUBY_VERSION}, but intended runtime JRuby version for jar file is #{config.jruby_version}"
|
315
|
+
puts "Mismatch between the JRuby versions used for compile and runtime is not supported by JRuby and may cause sudden errors"
|
316
|
+
raise "JRuby version mismatch: #{JRUBY_VERSION} != #{config.jruby_version}"
|
270
317
|
end
|
271
318
|
|
272
|
-
|
319
|
+
# Compile all .rb files in the current directory tree, but not in the gems directory
|
320
|
+
ruby_files = Find.find('.').select { |f| f =~ /\.rb$/ && !f.include?("#{File::SEPARATOR}gems#{File::SEPARATOR}") } # find all Ruby files in the current directory
|
273
321
|
|
274
322
|
# Exclude named files or directories from compiling
|
275
323
|
config.excludes_from_compile.each do |exclude|
|
@@ -291,6 +339,9 @@ module Jarbler
|
|
291
339
|
puts "'#{ruby_file}' is not compiled and will be included in the jar file as original Ruby file"
|
292
340
|
end
|
293
341
|
end
|
342
|
+
rescue Exception => e
|
343
|
+
puts "Builder.compile_ruby_files: Failed to compile Ruby files with #{e.class}\n#{e.message}"
|
344
|
+
raise
|
294
345
|
end
|
295
346
|
end
|
296
347
|
end
|
data/lib/jarbler/config.rb
CHANGED
@@ -3,7 +3,7 @@ require 'json'
|
|
3
3
|
|
4
4
|
module Jarbler
|
5
5
|
class Config
|
6
|
-
attr_accessor :jar_name, :includes, :excludes, :jruby_version, :executable, :executable_params, :compile_ruby_files, :excludes_from_compile
|
6
|
+
attr_accessor :jar_name, :includes, :excludes, :jruby_version, :executable, :executable_params, :compile_ruby_files, :excludes_from_compile, :compile_java_version
|
7
7
|
|
8
8
|
CONFIG_FILE = 'config/jarble.rb'
|
9
9
|
# create instance of Config class with defaults or from config file
|
@@ -31,9 +31,10 @@ module Jarbler
|
|
31
31
|
puts "No configuration file found at #{File.join(Dir.pwd, CONFIG_FILE)}. Using default values."
|
32
32
|
end
|
33
33
|
puts "Used configuration values are:"
|
34
|
+
puts " compile_java_version: #{config.compile_java_version}" if config.compile_ruby_files
|
34
35
|
puts " compile_ruby_files: #{config.compile_ruby_files}"
|
35
36
|
puts " excludes: #{config.excludes}"
|
36
|
-
puts " excludes_from_compile: #{config.excludes_from_compile}"
|
37
|
+
puts " excludes_from_compile: #{config.excludes_from_compile}" if config.compile_ruby_files
|
37
38
|
puts " executable: #{config.executable}"
|
38
39
|
puts " executable_params: #{config.executable_params}"
|
39
40
|
puts " includes: #{config.includes}"
|
@@ -45,6 +46,7 @@ module Jarbler
|
|
45
46
|
|
46
47
|
def initialize
|
47
48
|
@compile_ruby_files = false
|
49
|
+
@compile_java_version = nil # not specified by default
|
48
50
|
@excludes = %w(tmp/cache tmp/pids tmp/sockets vendor/bundle vendor/cache vendor/ruby)
|
49
51
|
@excludes_from_compile = []
|
50
52
|
@executable = 'bin/rails'
|
@@ -86,6 +88,11 @@ module Jarbler
|
|
86
88
|
# the original ruby files are not included in the jar file, so source code is not visible
|
87
89
|
# config.compile_ruby_files = #{compile_ruby_files}
|
88
90
|
|
91
|
+
# Java version the compiled .class files should be compatible with
|
92
|
+
# controls the target and source version of the Java compiler (javac -source and -target)
|
93
|
+
# if not set then it generates the class file version according to your current Java version
|
94
|
+
# config.compile_java_version = '1.8'
|
95
|
+
|
89
96
|
# Directories or files to exclude from the compilation if compile_ruby_files = true
|
90
97
|
# The paths map to the final location of files or dirs in the jar file, e.g. config.excludes_from_compile = ['gems', 'app_root/app/models']
|
91
98
|
# config.excludes_from_compile = #{excludes_from_compile}
|
@@ -143,12 +150,6 @@ module Jarbler
|
|
143
150
|
@jruby_version = response&.first&.first&.first&.version&.to_s
|
144
151
|
raise "Unable to determine the latest available version of jruby-jars gem!\nResponse = #{response.inspect}" unless @jruby_version
|
145
152
|
|
146
|
-
#command = "gem search --remote jruby-jars"
|
147
|
-
#lines = `#{command}`
|
148
|
-
#raise "Command \"#{command}\" failed with return code #{$?} and output:\n#{lines}" unless $?.success?
|
149
|
-
#jruby_jars_line = lines.match(/^jruby-jars \((.*)\)/)
|
150
|
-
#raise "No jruby-jars gem found in rubygems.org!" unless jruby_jars_line
|
151
|
-
#self.jruby_version = /\((.*?)\)/.match(jruby_jars_line.to_s)[1]
|
152
153
|
debug "Jarbler::Config.define_jruby_version: JRuby version from latest jruby-jars gem: #{jruby_version}"
|
153
154
|
end
|
154
155
|
end
|
@@ -159,7 +160,7 @@ module Jarbler
|
|
159
160
|
|
160
161
|
# Avoid exception if using depprecated config attribute include_gems_to_compile
|
161
162
|
def include_gems_to_compile=(_value)
|
162
|
-
puts "Configuration attribute 'include_gems_to_compile' is deprecated. Use 'excludes_from_compile = [
|
163
|
+
puts "Configuration attribute 'include_gems_to_compile' is deprecated. Use 'excludes_from_compile = [\"gems\"]' instead."
|
163
164
|
end
|
164
165
|
|
165
166
|
def validate_values
|
data/lib/jarbler/version.rb
CHANGED
data/log/.keep
ADDED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jarbler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ramm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Pack a Ruby app combined with JRuby runtime and all its Gem dependencies
|
14
14
|
into a jar file to simply run the app on any Java platform by '> java -jar file.jar'
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- lib/jarbler/builder.rb
|
35
35
|
- lib/jarbler/config.rb
|
36
36
|
- lib/jarbler/version.rb
|
37
|
+
- log/.keep
|
37
38
|
- sig/jarbler.rbs
|
38
39
|
homepage: https://github.com/rammpeter/jarbler
|
39
40
|
licenses:
|