jarbler 0.1.8 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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: []