jarbler 0.1.8 → 0.2.1

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: 5de0d62c0ac312179bc506c3cda49ed463e72e11e9d0c153551fc90ce8aa2fee
4
- data.tar.gz: 94c1e161336e09cf9e4188819298ee7dbffd6702b1b6d3909993911a5ae886c8
3
+ metadata.gz: 97f5261d55e15e23454414413af5f467bfdf5c2554916574269d6fa99f4a411a
4
+ data.tar.gz: 5a77de393585a7fa444157ebc2e7835d6d39e2e0e004ade0f840d9f2f9abcff9
5
5
  SHA512:
6
- metadata.gz: 18f5af166aaa6a994521cfdf6efee1ddbbd5f70f40a04a2288095d9de83e54e3767b26e3321426d06622efcc9fd62e5962e8b6638dc6786de0d82d25180fb739
7
- data.tar.gz: 7c3d03389ea1f41ab4e45e4988f0eae8e9fdb061bdf787922c27464ef46486c08543e3b2cad9ad8a862ba6e74f01629c776ad401a9a5ea2e1721c46a506a314e
6
+ metadata.gz: ad30f274db2a26f844df82f295b95f9bdcd9a023f35bbc83a6d2b7ec44b77a4dd0b8ca5ca66bb3f46818acf927d2e72efefb0f8b2669b058f5f51b9dacdb6d49
7
+ data.tar.gz: e07c531aa6082b3d186d2d3687d6a784b9b07593f4145e4d51bdd28247f57c710a35ed15196c18a0d3cb5a9f503808b242833709780b71442e0f293de1fe0db4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.1] - 2024-06-13
4
+
5
+ - Ruby files remain originally in jar if compile fails for a single file.
6
+ - Gems are compiled only if include_gems_to_compile=true
7
+
8
+ ## [0.2.0] - 2024-06-12
9
+
10
+ - Add ahead of time compilation support for JRuby
11
+
3
12
  ## [0.1.6] - 2023-06-19
4
13
 
5
14
  - Bugfix: Do not clone default gems, because they are already included in the jruby jars standard library
data/README.md CHANGED
@@ -4,8 +4,8 @@ Pack a Ruby application into an executable jar file.
4
4
 
5
5
  Jarbler creates a self executing Java jar file containing a Ruby application and all its Gem dependencies.
6
6
 
7
- This tool is inspired by the widely used jRuby runner Warbler.
8
- The configured Ruby program is directly executed inside the JVM using the jRuby runtime jars.
7
+ This tool is inspired by the widely used JRuby runner Warbler.
8
+ The configured Ruby program is directly executed inside the JVM using the JRuby runtime jars.
9
9
 
10
10
  ## Installation
11
11
 
@@ -31,7 +31,7 @@ To adjust Jarbler's configuration, modify the settings in config file ´config/j
31
31
 
32
32
  ### Preconditions
33
33
  * Dependency handling should be based on Bundler (existence of Gemfile is required)
34
- * The Ruby app should be capable of running with jRuby
34
+ * The Ruby app should be capable of running with JRuby
35
35
  * Gems with native extensions should not be used (e.g. sassc)
36
36
  * if needed for development or test such Gems with native extensions should be moved to the development and test group in the Gemfile.
37
37
  * Otherwise the created jar file may not be executable on all platforms and Java versions.
@@ -50,22 +50,24 @@ To create a template config file with information about all the supported config
50
50
 
51
51
  $ jarble config
52
52
 
53
- The default configuration if focused on Ruby on Rails applications.<br>
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
- | executable | "bin/rails" | The ruby file to run at execution of jar file |
59
- | executable_params | ["server", "-e", "production", "-p", "8080"] | Command line parameters to be used for the ruby executable |
60
- | excludes | ["tmp/cache", "tmp/pids", ...] (see generated template file for whole content) | The files and dirs of the project to exlude from the include option |
61
- | includes | ["app", "bin", "config", ...] (see generated template file for whole content) | The files and dirs of the project to include in the jar file |
62
- | jar_name | &lt; Name of project dir &gt;.jar | The name of the generated jar file |
63
- | jruby_version | The current most recent jRuby version | The version of the jRuby runtime to use |
56
+ | Option | Default value | Description |
57
+ |-------------------------|--------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
58
+ | compile_ruby_files | false | Ahead of time compilation of all .rb files of application and Gem dependencies to .class files. Only store .class files in jar. 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 | ["tmp/cache", "tmp/pids", ...] (see generated template file for whole content) | The files and dirs of the project to exlude from the include option |
62
+ | include_gems_to_compile | false | Should .rb files of the project gems also be compiled if compile_ruby_files = true |
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 | The current most recent JRuby version | The version of the JRuby runtime to use |
64
66
 
65
67
 
66
68
  ## Troubleshooting
67
69
  * Set DEBUG=true in environment to get additional runtime information
68
- * The temporary folder with the extracted app and jRuby runtime files is not deleted after execution if DEBUG is set.
70
+ * The temporary folder with the extracted app and JRuby runtime files is not deleted after execution if DEBUG is set.
69
71
 
70
72
  ### Possible error messages
71
73
  * Gem::LoadError: You have already activated ..., but your Gemfile requires ... . Since ... is a default gem, you can either remove your dependency on it or try updating to a newer version of bundler that supports net-protocol as a default gem.
data/jarbler.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["Peter@ramm-oberhermsdorf.de"]
10
10
 
11
11
  spec.summary = "Pack a Ruby app into a Java jar file"
12
- spec.description = "Pack a Ruby app combined with jRuby runtime and all its Gem dependencies into a jar file to simply run the app on any Java platform by '> java -jar file.jar'"
12
+ spec.description = "Pack a Ruby app combined with JRuby runtime and all its Gem dependencies into a jar file to simply run the app on any Java platform by '> java -jar file.jar'"
13
13
  spec.homepage = "https://github.com/rammpeter/jarbler"
14
14
  spec.license = "MIT"
15
15
  spec.required_ruby_version = ">= 2.6.0"
@@ -87,6 +87,13 @@ class JarMain {
87
87
  executable = prop.getProperty("jarbler.executable");
88
88
  executable_params = prop.getProperty("jarbler.executable_params");
89
89
 
90
+ Boolean compile_ruby_files = Boolean.parseBoolean(prop.getProperty("jarbler.compile_ruby_files", "false"));
91
+ if (compile_ruby_files) {
92
+ debug("Set system property jruby.aot.loadClasses = true");
93
+ // ensure that .class files are loaded at require time if rb files are not present
94
+ System.setProperty("jruby.aot.loadClasses", "true");
95
+ }
96
+
90
97
  // throw exception if executable is null
91
98
  if (executable == null) {
92
99
  throw new RuntimeException("Property 'executable' definition missing in jarbler.properties");
@@ -129,12 +136,12 @@ class JarMain {
129
136
  }
130
137
  }
131
138
 
132
- debug("jRuby program starts with the following arguments: ");
139
+ debug("JRuby program starts with the following arguments: ");
133
140
  for (String arg : mainArgs) {
134
141
  debug(" - " + arg);
135
142
  }
136
143
 
137
- debug("jRuby set property 'user.dir' to '" + app_root + "'");
144
+ debug("JRuby set property 'user.dir' to '" + app_root + "'");
138
145
  System.setProperty("user.dir", app_root);
139
146
  // call the method org.jruby.Main.main
140
147
  debug("Calling org.jruby.Main.main with: "+ mainArgs);
@@ -49,6 +49,7 @@ module Jarbler
49
49
  java_executable_params += "#{param} "
50
50
  end
51
51
  file.write("jarbler.executable_params=#{java_executable_params.strip}\n")
52
+ file.write("jarbler.compile_ruby_files=#{config.compile_ruby_files}\n")
52
53
  end
53
54
 
54
55
  # remove files and directories from excludes, if they exist (after copying the rails project and the gems)
@@ -62,6 +63,8 @@ module Jarbler
62
63
  end
63
64
  end
64
65
 
66
+ compile_ruby_files if config.compile_ruby_files
67
+
65
68
  exec_command "jar cfm #{config.jar_name} Manifest.txt *" # create the jar file
66
69
 
67
70
  # place the jar in project directory
@@ -202,7 +205,7 @@ module Jarbler
202
205
 
203
206
  # Copy the jruby-jars to the staging directory
204
207
  # @param [String] staging_dir Path to the staging directory
205
- # @return [String] the minor ruby version of the jRuby jars with patch level set to 0
208
+ # @return [String] the minor ruby version of the JRuby jars with patch level set to 0
206
209
  def copy_jruby_jars_to_staging(staging_dir)
207
210
 
208
211
  # Ensure that jruby-jars gem is installed, otherwise install it. Accepts also bundler path in .bundle/config
@@ -211,7 +214,7 @@ module Jarbler
211
214
  raise "jruby-jars gem not installed in version #{config.jruby_version}" if installed.empty?
212
215
 
213
216
  jruby_jars_location = installed[0]&.full_gem_path
214
- debug "jRuby jars installed at: #{jruby_jars_location}"
217
+ debug "JRuby jars installed at: #{jruby_jars_location}"
215
218
 
216
219
  # Get the location of the jruby-jars gem
217
220
  # spec = Gem::Specification.find_by_name('jruby-jars', config.jruby_version)
@@ -220,14 +223,14 @@ module Jarbler
220
223
  file_utils_copy("#{jruby_jars_location}/lib/jruby-core-#{config.jruby_version}-complete.jar", staging_dir)
221
224
  file_utils_copy("#{jruby_jars_location}/lib/jruby-stdlib-#{config.jruby_version}.jar", staging_dir)
222
225
 
223
- # Get the according Ruby version for the current jRuby version
226
+ # Get the according Ruby version for the current JRuby version
224
227
  lines = exec_command "java -cp #{jruby_jars_location}/lib/jruby-core-#{config.jruby_version}-complete.jar org.jruby.Main --version"
225
228
  match_result = lines.match(/\(.*\)/)
226
- raise "Could not determine Ruby version for jRuby #{config.jruby_version} in following output:\n#{lines}" unless match_result
229
+ raise "Could not determine Ruby version for JRuby #{config.jruby_version} in following output:\n#{lines}" unless match_result
227
230
  ruby_version = match_result[0].tr('()', '')
228
- debug "Corresponding Ruby version for jRuby (#{config.jruby_version}): #{ruby_version}"
231
+ debug "Corresponding Ruby version for JRuby (#{config.jruby_version}): #{ruby_version}"
229
232
  ruby_minor_version = ruby_version.split('.')[0..1].join('.') + '.0'
230
- debug "Corresponding Ruby minor version for jRuby (#{config.jruby_version}): #{ruby_minor_version}"
233
+ debug "Corresponding Ruby minor version for JRuby (#{config.jruby_version}): #{ruby_minor_version}"
231
234
  ruby_minor_version
232
235
  end
233
236
 
@@ -255,6 +258,38 @@ module Jarbler
255
258
  puts "Error copying #{source} to #{destination}"
256
259
  raise
257
260
  end
258
- end
259
261
 
262
+ # Compile all Ruby files in the current directory (staging directory)
263
+ def compile_ruby_files
264
+ require 'jruby/jrubyc'
265
+
266
+ puts "Compiling all .rb files to .class files"
267
+ # Inform if used JRuby version is different from the intended runtime JRuby version
268
+ if JRUBY_VERSION != config.jruby_version
269
+ 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}"
270
+ end
271
+
272
+ ruby_files = Find.find('.').select { |f| f =~ /\.rb$/ } # find all Ruby files in the current directory
273
+
274
+ if !config.include_gems_to_compile
275
+ ruby_files = ruby_files.select { |f| !(f =~ /\.#{File::SEPARATOR}gems#{File::SEPARATOR}/) } # Exclude ./gems/* directories from compiling
276
+ end
277
+
278
+ ruby_files.each do |ruby_file|
279
+ debug "Compile Ruby file #{ruby_file}"
280
+ full_file_name = File.join(Dir.pwd, ruby_file) # full name including path is required by the JRuby compiler
281
+ begin
282
+ status = JRuby::Compiler::compile_argv([full_file_name]) # compile the Ruby file
283
+ if status == 0
284
+ File.delete(full_file_name) # remove the original Ruby file to ensure that the compiled class file is used
285
+ else
286
+ raise "Return status != 0"
287
+ end
288
+ rescue Exception => e
289
+ puts "Error compiling Ruby file '#{ruby_file}': #{e.class}:#{e.message}"
290
+ puts "'#{ruby_file}' is not compiled and will be included in the jar file as original Ruby file"
291
+ end
292
+ end
293
+ end
294
+ end
260
295
  end
@@ -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
6
+ attr_accessor :jar_name, :includes, :excludes, :jruby_version, :executable, :executable_params, :compile_ruby_files, :include_gems_to_compile
7
7
 
8
8
  CONFIG_FILE = 'config/jarble.rb'
9
9
  # create instance of Config class with defaults or from config file
@@ -19,16 +19,22 @@ module Jarbler
19
19
  config = Config.new
20
20
  end
21
21
  config.define_jruby_version
22
+ # Replace .rb with .class if compile_ruby_files is true
23
+ config.executable = config.executable.sub(/\.rb$/, '.class') if config.compile_ruby_files
24
+
25
+ config.validate_values
22
26
  config
23
27
  end
24
28
 
25
29
  def initialize
26
- @jar_name = File.basename(Dir.pwd) + '.jar'
27
- @includes = %w(app bin config config.ru db Gemfile Gemfile.lock lib log public Rakefile script vendor tmp)
30
+ @compile_ruby_files = false
28
31
  @excludes = %w(tmp/cache tmp/pids tmp/sockets vendor/bundle vendor/cache vendor/ruby)
29
- @jruby_version = nil # determined automatically at runtime
30
32
  @executable = 'bin/rails'
31
33
  @executable_params = %w(server -e production -p 8080)
34
+ @include_gems_to_compile = false
35
+ @includes = %w(app bin config config.ru db Gemfile Gemfile.lock lib log public Rakefile script vendor tmp)
36
+ @jar_name = File.basename(Dir.pwd) + '.jar'
37
+ @jruby_version = nil # determined automatically at runtime
32
38
  # execute additional block if given
33
39
  yield self if block_given?
34
40
  end
@@ -47,9 +53,9 @@ module Jarbler
47
53
  # config.excludes = #{excludes}
48
54
  # config.excludes << 'additional'
49
55
 
50
- # Use certail jRuby version
56
+ # Use certain JRuby version
51
57
  # if not set (nil) then the version defined in .ruby-version
52
- # if not jRuby version defined here or in .ruby-version then the latest available jRuby version is used
58
+ # if not JRuby version defined here or in .ruby-version then the latest available JRuby version is used
53
59
  # config.jruby_version = '9.2.3.0'
54
60
  # config.jruby_version = nil
55
61
 
@@ -58,6 +64,14 @@ module Jarbler
58
64
 
59
65
  # Additional command line parameters for the Ruby executable
60
66
  # config.executable_params = #{executable_params}
67
+
68
+ # Compile the ruby files of the project to Java .class files with JRuby's ahead-of-time compiler?
69
+ # the original ruby files are not included in the jar file, so source code is not visible
70
+ # config.compile_ruby_files = #{compile_ruby_files}
71
+
72
+ # Compile also the .rb files of the gems of the project to Java .class files?
73
+ # config.include_gems_to_compile = #{include_gems_to_compile}
74
+
61
75
  ".split("\n"))
62
76
  end
63
77
 
@@ -83,15 +97,15 @@ module Jarbler
83
97
  puts "Jarbler: Created config file #{Dir.pwd}/#{CONFIG_FILE}"
84
98
  end
85
99
 
86
- # define jRuby version if not set in config file
100
+ # define JRuby version if not set in config file
87
101
  def define_jruby_version
88
102
  unless @jruby_version # not defined in config file
89
103
  if File.exist?('.ruby-version')
90
104
  # read the file RAILS_ROOT/.ruby-version starting from char at position 6 to the end of the line
91
105
  self.jruby_version = File.read('.ruby-version')[6..20].strip
92
- debug "jRuby version from .ruby-version file: #{jruby_version}"
106
+ debug "JRuby version from .ruby-version file: #{jruby_version}"
93
107
  else
94
- # no .ruby-version file, use jRuby version of the latest Gem
108
+ # no .ruby-version file, use JRuby version of the latest Gem
95
109
  # Fetch the gem specification from Rubygems.org
96
110
  # search for the gem and get the JSON response
97
111
  response = Gem::SpecFetcher.fetcher.search_for_dependency(Gem::Dependency.new('jruby-jars'))
@@ -105,7 +119,7 @@ module Jarbler
105
119
  #jruby_jars_line = lines.match(/^jruby-jars \((.*)\)/)
106
120
  #raise "No jruby-jars gem found in rubygems.org!" unless jruby_jars_line
107
121
  #self.jruby_version = /\((.*?)\)/.match(jruby_jars_line.to_s)[1]
108
- debug "jRuby version from latest jruby-jars gem: #{jruby_version}"
122
+ debug "JRuby version from latest jruby-jars gem: #{jruby_version}"
109
123
  end
110
124
  end
111
125
  end
@@ -113,5 +127,16 @@ module Jarbler
113
127
  def debug(msg)
114
128
  puts msg if ENV['DEBUG']
115
129
  end
130
+
131
+ def validate_values
132
+ raise "Invalid config value for jar name: #{jar_name}" unless jar_name =~ /\w+/
133
+ raise "Invalid config value for executable: #{executable}" unless executable =~ /\w+/
134
+ raise "Invalid config value for executable params: #{executable_params}" unless executable_params.is_a?(Array)
135
+ raise "Invalid config value for includes: #{includes}" unless includes.is_a?(Array)
136
+ raise "Invalid config value for excludes: #{excludes}" unless excludes.is_a?(Array)
137
+ raise "Invalid config value for compile_ruby_files: #{compile_ruby_files}" unless [true, false].include?(compile_ruby_files)
138
+ raise "compile_ruby_files = true is supported only with JRuby! Current runtime is '#{RUBY_ENGINE}'" if compile_ruby_files && (defined?(RUBY_ENGINE) && RUBY_ENGINE != 'jruby')
139
+ raise "include_gems_to_compile = true is supported only if compile_ruby_files = true!" if include_gems_to_compile && !compile_ruby_files
140
+ end
116
141
  end
117
142
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jarbler
4
- VERSION = "0.1.8"
5
- VERSION_DATE = "2024-03-04"
4
+ VERSION = "0.2.1"
5
+ VERSION_DATE = "2024-06-13"
6
6
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jarbler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ramm
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-04 00:00:00.000000000 Z
11
+ date: 2024-06-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Pack a Ruby app combined with jRuby runtime and all its Gem dependencies
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'
15
15
  email:
16
16
  - Peter@ramm-oberhermsdorf.de
@@ -42,7 +42,7 @@ metadata:
42
42
  homepage_uri: https://github.com/rammpeter/jarbler
43
43
  source_code_uri: https://github.com/rammpeter/jarbler
44
44
  changelog_uri: https://github.com/rammpeter/jarbler/CHANGELOG.md
45
- post_install_message:
45
+ post_install_message:
46
46
  rdoc_options: []
47
47
  require_paths:
48
48
  - lib
@@ -57,8 +57,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
57
  - !ruby/object:Gem::Version
58
58
  version: '0'
59
59
  requirements: []
60
- rubygems_version: 3.5.6
61
- signing_key:
60
+ rubygems_version: 3.3.27
61
+ signing_key:
62
62
  specification_version: 4
63
63
  summary: Pack a Ruby app into a Java jar file
64
64
  test_files: []