jarbler 0.1.8 → 0.2.0

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: b29152eb922ef6ae438fb5facfd9c3a7cc8df920ad350254729aca4ad1cccff2
4
+ data.tar.gz: 632b9ca7b2663a563e5cecdad71c789b3c40f205ff8365c36f37d7b0abe284a6
5
5
  SHA512:
6
- metadata.gz: 18f5af166aaa6a994521cfdf6efee1ddbbd5f70f40a04a2288095d9de83e54e3767b26e3321426d06622efcc9fd62e5962e8b6638dc6786de0d82d25180fb739
7
- data.tar.gz: 7c3d03389ea1f41ab4e45e4988f0eae8e9fdb061bdf787922c27464ef46486c08543e3b2cad9ad8a862ba6e74f01629c776ad401a9a5ea2e1721c46a506a314e
6
+ metadata.gz: 3e560cd914882b62e45ebe20f10b2d7cd9eb7170be0412008afb970dbc1c571fa776d26aa8bf11d49aa205fdd5e05def9d121c876ce897a79b6ddbb8e6df92a4
7
+ data.tar.gz: 8275b73c22ea2c91cf1db36649a0510b8fbe41d85be39a1ba093f84c4b78adec0cb74ce5345ebe5c4a925f4393ddefa173aebed27b2decbf2eea57f7e4ec3ce0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2024-06-12
4
+
5
+ - Add ahead of time compilation support for JRuby
6
+
3
7
  ## [0.1.6] - 2023-06-19
4
8
 
5
9
  - 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,23 @@ 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
+ | includes | ["app", "bin", "config", ...] (see generated template file for whole content) | The files and dirs of the project to include in the jar file |
63
+ | jar_name | &lt; Name of project dir &gt;.jar | The name of the generated jar file |
64
+ | jruby_version | The current most recent JRuby version | The version of the JRuby runtime to use |
64
65
 
65
66
 
66
67
  ## Troubleshooting
67
68
  * 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.
69
+ * The temporary folder with the extracted app and JRuby runtime files is not deleted after execution if DEBUG is set.
69
70
 
70
71
  ### Possible error messages
71
72
  * 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,25 @@ 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$/ }
273
+ ruby_files.each do |ruby_file|
274
+ debug "Compile Ruby file #{ruby_file}"
275
+ full_file_name = File.join(Dir.pwd, ruby_file) # full name including path is required by the JRuby compiler
276
+ status = JRuby::Compiler::compile_argv([full_file_name]) # compile the Ruby file
277
+ raise "Error compiling Ruby file #{ruby_file}" if status != 0
278
+ File.delete(full_file_name) # remove the original Ruby file to ensure that the compiled class file is used
279
+ end
280
+ end
281
+ end
260
282
  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
7
7
 
8
8
  CONFIG_FILE = 'config/jarble.rb'
9
9
  # create instance of Config class with defaults or from config file
@@ -19,10 +19,15 @@ 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
30
+ @compile_ruby_files = false
26
31
  @jar_name = File.basename(Dir.pwd) + '.jar'
27
32
  @includes = %w(app bin config config.ru db Gemfile Gemfile.lock lib log public Rakefile script vendor tmp)
28
33
  @excludes = %w(tmp/cache tmp/pids tmp/sockets vendor/bundle vendor/cache vendor/ruby)
@@ -36,6 +41,10 @@ module Jarbler
36
41
  # Generate the template config file based on default values
37
42
  def create_config_file
38
43
  write_config_file("\
44
+ # Compile the ruby files of the project to Java .class files with JRuby's ahead-of-time compiler
45
+ # the original ruby files are not included in the jar file, so source code is not visible
46
+ # config.compile_ruby_files = #{compile_ruby_files}
47
+
39
48
  # Name of the generated jar file
40
49
  # config.jar_name = '#{jar_name}'
41
50
 
@@ -47,9 +56,9 @@ module Jarbler
47
56
  # config.excludes = #{excludes}
48
57
  # config.excludes << 'additional'
49
58
 
50
- # Use certail jRuby version
59
+ # Use certain JRuby version
51
60
  # 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
61
+ # if not JRuby version defined here or in .ruby-version then the latest available JRuby version is used
53
62
  # config.jruby_version = '9.2.3.0'
54
63
  # config.jruby_version = nil
55
64
 
@@ -83,15 +92,15 @@ module Jarbler
83
92
  puts "Jarbler: Created config file #{Dir.pwd}/#{CONFIG_FILE}"
84
93
  end
85
94
 
86
- # define jRuby version if not set in config file
95
+ # define JRuby version if not set in config file
87
96
  def define_jruby_version
88
97
  unless @jruby_version # not defined in config file
89
98
  if File.exist?('.ruby-version')
90
99
  # read the file RAILS_ROOT/.ruby-version starting from char at position 6 to the end of the line
91
100
  self.jruby_version = File.read('.ruby-version')[6..20].strip
92
- debug "jRuby version from .ruby-version file: #{jruby_version}"
101
+ debug "JRuby version from .ruby-version file: #{jruby_version}"
93
102
  else
94
- # no .ruby-version file, use jRuby version of the latest Gem
103
+ # no .ruby-version file, use JRuby version of the latest Gem
95
104
  # Fetch the gem specification from Rubygems.org
96
105
  # search for the gem and get the JSON response
97
106
  response = Gem::SpecFetcher.fetcher.search_for_dependency(Gem::Dependency.new('jruby-jars'))
@@ -105,7 +114,7 @@ module Jarbler
105
114
  #jruby_jars_line = lines.match(/^jruby-jars \((.*)\)/)
106
115
  #raise "No jruby-jars gem found in rubygems.org!" unless jruby_jars_line
107
116
  #self.jruby_version = /\((.*?)\)/.match(jruby_jars_line.to_s)[1]
108
- debug "jRuby version from latest jruby-jars gem: #{jruby_version}"
117
+ debug "JRuby version from latest jruby-jars gem: #{jruby_version}"
109
118
  end
110
119
  end
111
120
  end
@@ -113,5 +122,15 @@ module Jarbler
113
122
  def debug(msg)
114
123
  puts msg if ENV['DEBUG']
115
124
  end
125
+
126
+ def validate_values
127
+ raise "Invalid config value for jar name: #{jar_name}" unless jar_name =~ /\w+/
128
+ raise "Invalid config value for executable: #{executable}" unless executable =~ /\w+/
129
+ raise "Invalid config value for executable params: #{executable_params}" unless executable_params.is_a?(Array)
130
+ raise "Invalid config value for includes: #{includes}" unless includes.is_a?(Array)
131
+ raise "Invalid config value for excludes: #{excludes}" unless excludes.is_a?(Array)
132
+ raise "Invalid config value for compile_ruby_files: #{compile_ruby_files}" unless [true, false].include?(compile_ruby_files)
133
+ 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')
134
+ end
116
135
  end
117
136
  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.0"
5
+ VERSION_DATE = "2024-06-12"
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.0
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-12 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: []