jarbler 0.3.4 → 0.3.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d00ae03fa03fd70f85ce56da587974f9f2a5645ff977beb6c2a4e9188e92ce53
4
- data.tar.gz: 7b1b592f4459f728b3838eaa6d40b9f60a78350413f8bbe34fe59c7160fd23ef
3
+ metadata.gz: 1496bf31678cf15945cd367d656a6717df35552c3deacf4e44d0f0d8267e26a0
4
+ data.tar.gz: 401efdc3ab67e9e913de4550ea108dc13899ececc0ab1b14267451e731803159
5
5
  SHA512:
6
- metadata.gz: d4ca329fcd32d2833608ffff76dfecb923dacc72cc1027ed661aa6e2572f2d2a8b026c364597b831107e0e069604bd48ad54af79d5253787007efeba67464b20
7
- data.tar.gz: 24fab155519254614a9b0ca86477d01a6c5e25f7394c2b0545eac82a3c2989fe72408a6100dc256eba2e68ba580143f1c47431f3acda2028d766a2343ab0ae4e
6
+ metadata.gz: 39a464b266c5f06ebf2270e117ba0f81a7fae012c70d5a18737b89e72ab9c3f99ea44d0aa5d898e55b4381789a21e7b2c2e1a1abbc3e781a0d10da12f272cce2
7
+ data.tar.gz: 449426ef9a89c170efc469fc87ad179c2c89438580fac0cecbf19c6b06d7af048f0e345f3569aa46a6d4578ef3422602ea5f6acc84b3102544da8a43f7b4863c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.6] - 2025-03-31
4
+
5
+ - remove temporary folder with extracted jar content after termination of Ruby code even if Ruby code terminates the JVM hard with 'exit' or 'System.exit'
6
+ - provide exit code of Ruby code as exit code of the jar file execution
7
+
8
+ ## [0.3.5] - 2025-03-22
9
+
10
+ - new config attribute "config.compile_java_version" allows control of setting for "javac -source and -target" for AOT compilation
11
+ - fix typo with smart quotes in config.rb
12
+
3
13
  ## [0.3.4] - 2025-03-07
4
14
 
5
15
  - Warning if Ruby-specific environment variables (GEM_HOME etc.) are set which may cause malfunction of app in jar file
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
- | compile_ruby_files | false | Ahead of time compilation of all .rb files of the application to .class files. Onl the .class files are stored in the jar file. The Gem dependencies are not compiled. Requires JRuby runtime. |
59
- | 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. |
60
- | executable_params | ["server", "-e", "production", "-p", "8080"] | Command line parameters to be used for the ruby executable |
61
- | 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"] ) |
62
- | 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 |
63
- | includes | ["app", "bin", "config", ...] (see generated template file for whole content) | The files and dirs of the project to include in the jar file |
64
- | jar_name | &lt; Name of project dir &gt;.jar | The name of the generated jar file |
65
- | 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 |
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 | &lt; Name of project dir &gt;.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
@@ -33,6 +33,9 @@ import java.security.ProtectionDomain;
33
33
 
34
34
  class JarMain {
35
35
 
36
+ // declare as class variable to be used in addShutdownHook
37
+ private static URLClassLoader classLoader = null;
38
+
36
39
  // executed by java -jar <jar file name>
37
40
  public static void main(String[] args) {
38
41
  debug("Start java process in jar file "+jar_file_name());
@@ -113,7 +116,7 @@ class JarMain {
113
116
  create_bundle_config(app_root, gem_home);
114
117
 
115
118
  // Load the Jar file
116
- URLClassLoader classLoader = new URLClassLoader(new URL[]{
119
+ classLoader = new URLClassLoader(new URL[]{
117
120
  jrubyCoreFile.toURI().toURL(),
118
121
  jrubyStdlibFile.toURI().toURL()
119
122
  //new URL("file:/" + jrubyCoreFile.getAbsolutePath()),
@@ -159,19 +162,39 @@ class JarMain {
159
162
  debug(" - " + arg);
160
163
  }
161
164
 
165
+ // Add code to execute at System.exit
166
+ // ensure cleanup of the temporary directory also at hard exit in Ruby code like 'exit' or 'System.exit'
167
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
168
+ debug("Execute shutdown hook");
169
+ try {
170
+ if (classLoader != null) {
171
+ // Free the JRuby jars to allow deletion of the temporary directory
172
+ classLoader.close();
173
+ classLoader = null; // Remove reference
174
+ System.gc(); // Suggest garbage collection
175
+ }
176
+ // remove the temp directory newFolder if not DEBUG mode
177
+ if (debug_active()) {
178
+ System.out.println("DEBUG mode is active, temporary folder is not removed at process termination: "+ newFolder.getAbsolutePath());
179
+ } else {
180
+ deleteFolder(newFolder);
181
+ }
182
+ } catch (Exception e) {
183
+ System.err.println("Exception in shutdown hook: "+ e.getMessage());
184
+ e.printStackTrace();
185
+ }
186
+ }));
187
+
162
188
  // call the method org.jruby.Main.main
163
189
  debug("Calling org.jruby.Main.main with: "+ mainArgs);
164
190
  mainMethod.invoke(null, (Object)mainArgs.toArray(new String[mainArgs.size()]));
165
- // TODO: evaluate return value
166
191
  } catch (Exception e) {
167
192
  e.printStackTrace();
193
+ System.exit(1); // signal unsuccessful termination
168
194
  } finally {
169
- // remove the temp directory newFolder if not DEBUG mode
170
- if (System.getenv("DEBUG") != null) {
171
- System.out.println("DEBUG mode is active, temporary folder is not removed at process termination: "+ newFolder.getAbsolutePath());
172
- } else {
173
- deleteFolder(newFolder);
174
- }
195
+ // Called only if the JVM is not terminated by System.exit before, see addShutdownHook
196
+ // This code is not executed if called 'exit' or 'System.exit' in Ruby code before
197
+ debug("Applicaton finished in finalize block");
175
198
  }
176
199
  }
177
200
 
@@ -240,24 +263,32 @@ class JarMain {
240
263
 
241
264
  }
242
265
 
266
+ private static boolean debug_active() {
267
+ String debug = System.getenv("DEBUG");
268
+ return debug != null && debug.toUpperCase().equals("TRUE");
269
+ }
270
+
243
271
  private static void debug(String msg) {
244
- if (System.getenv("DEBUG") != null) {
272
+ if (debug_active()) {
245
273
  System.err.println(msg);
246
274
  }
247
275
  }
248
276
 
249
- private static void deleteFolder(File file){
250
- for (File subFile : file.listFiles()) {
251
- if(subFile.isDirectory()) {
252
- deleteFolder(subFile);
253
- } else {
254
- subFile.delete();
255
- }
256
- }
257
- file.delete();
277
+ private static void deleteFolder(File file) {
278
+ try
279
+ {
280
+ if (file.isDirectory()) {
281
+ File[] entries = file.listFiles();
282
+ for (File currentFile: entries) {
283
+ deleteFolder(currentFile);
284
+ }
285
+ }
286
+ file.delete();
287
+ } catch(Throwable t) {
288
+ System.err.println("Could not DELETE file: " + file.getAbsolutePath() + " - " + t.getMessage());
289
+ }
258
290
  }
259
291
 
260
-
261
292
  private static void create_bundle_config(String app_root, String gem_path) throws IOException {
262
293
  File bundle_config = new File(app_root + File.separator + ".bundle");
263
294
  bundle_config.mkdir();
@@ -19,8 +19,12 @@ module Jarbler
19
19
  app_root = Dir.pwd
20
20
  debug "Project dir: #{app_root}"
21
21
 
22
+ source_and_target = if config.compile_java_version
23
+ "-source #{config.compile_java_version} -target #{config.compile_java_version}"
24
+ end
25
+
22
26
  ruby_minor_version = copy_jruby_jars_to_staging(staging_dir) # Copy the jruby jars to the staging directory
23
- exec_command "javac -nowarn -Xlint:deprecation -source 8 -target 8 -d #{staging_dir} #{__dir__}/JarMain.java" # Compile the Java files
27
+ exec_command "javac -nowarn -Xlint:deprecation #{source_and_target} -d #{staging_dir} #{__dir__}/JarMain.java" # Compile the Java files
24
28
 
25
29
  # Copy the application project to the staging directory
26
30
  FileUtils.mkdir_p("#{staging_dir}/app_root")
@@ -308,6 +312,8 @@ module Jarbler
308
312
  # Inform if used JRuby version is different from the intended runtime JRuby version
309
313
  if JRUBY_VERSION != config.jruby_version
310
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}"
311
317
  end
312
318
 
313
319
  # Compile all .rb files in the current directory tree, but not in the gems directory
@@ -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}
@@ -153,7 +160,7 @@ module Jarbler
153
160
 
154
161
  # Avoid exception if using depprecated config attribute include_gems_to_compile
155
162
  def include_gems_to_compile=(_value)
156
- puts "Configuration attribute 'include_gems_to_compile' is deprecated. Use 'excludes_from_compile = [\”gems\”]' instead."
163
+ puts "Configuration attribute 'include_gems_to_compile' is deprecated. Use 'excludes_from_compile = [\"gems\"]' instead."
157
164
  end
158
165
 
159
166
  def validate_values
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jarbler
4
- VERSION = "0.3.4"
5
- VERSION_DATE = "2025-03-07"
4
+ VERSION = "0.3.6"
5
+ VERSION_DATE = "2025-03-31"
6
6
  end
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
4
+ version: 0.3.6
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-07 00:00:00.000000000 Z
11
+ date: 2025-04-01 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'