Skip to content

Commit a7e12df

Browse files
authored
Fix: driver loading when file not accessible (#15)
these are non-critical improvements for (input) driver loading. issues are kept on the original repo since they concern the plugin. this is expected to resolve logstash-plugins/logstash-input-jdbc#369 (also partially relates to logstash-plugins/logstash-input-jdbc#362)
1 parent e6f5195 commit a7e12df

File tree

5 files changed

+76
-28
lines changed

5 files changed

+76
-28
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## N.X.T
2+
- Fix: driver loading when file not accessible [#15](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/15)
3+
14
## 5.0.0
25
- Initial Release of JDBC Integration Plugin, incorporating [logstash-input-jdbc](https://github.com/logstash-plugins/logstash-input-jdbc), [logstash-filter-jdbc_streaming](https://github.com/logstash-plugins/logstash-filter-jdbc_streaming) and
36
[logstash-filter-jdbc_static](https://github.com/logstash-plugins/logstash-filter-jdbc_static)

docs/input-jdbc.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ required you can pass them separated by a comma.
339339
NOTE: If not provided, Plugin will look for the driver class in the Logstash Java classpath. Additionally, if the library
340340
does not appear to be being loaded correctly via this setting, placing the relevant jar(s) in the Logstash Java
341341
classpath rather than via this setting may help.
342+
Please also make sure the path is readable by the Logstash process (e.g. `logstash` user when running as a service).
342343

343344
[id="plugins-{type}s-{plugin}-jdbc_fetch_size"]
344345
===== `jdbc_fetch_size`

lib/logstash/inputs/jdbc.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ def set_value_tracker(instance)
270270
end
271271

272272
def run(queue)
273+
load_driver
273274
if @schedule
274275
@scheduler = Rufus::Scheduler.new(:max_work_threads => 1)
275276
@scheduler.cron @schedule do

lib/logstash/plugin_mixins/jdbc/jdbc.rb

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -139,47 +139,58 @@ def jdbc_connect
139139

140140
private
141141

142+
def load_driver
143+
if @drivers_loaded.false?
144+
require "java"
145+
require "sequel"
146+
require "sequel/adapters/jdbc"
147+
148+
load_driver_jars
149+
begin
150+
Sequel::JDBC.load_driver(@jdbc_driver_class)
151+
rescue Sequel::AdapterNotFound => e # Sequel::AdapterNotFound, "#{@jdbc_driver_class} not loaded"
152+
# fix this !!!
153+
message = if jdbc_driver_library_set?
154+
"Are you sure you've included the correct jdbc driver in :jdbc_driver_library?"
155+
else
156+
":jdbc_driver_library is not set, are you sure you included " +
157+
"the proper driver client libraries in your classpath?"
158+
end
159+
raise LogStash::PluginLoadingError, "#{e}. #{message}"
160+
end
161+
@drivers_loaded.make_true
162+
end
163+
end
164+
142165
def load_driver_jars
143-
unless @jdbc_driver_library.nil? || @jdbc_driver_library.empty?
166+
if jdbc_driver_library_set?
144167
@jdbc_driver_library.split(",").each do |driver_jar|
168+
@logger.debug("loading #{driver_jar}")
169+
# load 'driver.jar' is different than load 'some.rb' as it only causes the file to be added to
170+
# JRuby's class-loader lookup (class) path - won't raise a LoadError when file is not readable
171+
unless FileTest.readable?(driver_jar)
172+
raise LogStash::PluginLoadingError, "unable to load #{driver_jar} from :jdbc_driver_library, " +
173+
"file not readable (please check user and group permissions for the path)"
174+
end
145175
begin
146-
@logger.debug("loading #{driver_jar}")
147-
# Use https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby#from-jar-files to make classes from jar
148-
# available
149176
require driver_jar
150177
rescue LoadError => e
151178
raise LogStash::PluginLoadingError, "unable to load #{driver_jar} from :jdbc_driver_library, #{e.message}"
179+
rescue StandardError => e
180+
raise LogStash::PluginLoadingError, "unable to load #{driver_jar} from :jdbc_driver_library, #{e}"
152181
end
153182
end
154183
end
155184
end
156185

157-
private
158-
def open_jdbc_connection
159-
require "java"
160-
require "sequel"
161-
require "sequel/adapters/jdbc"
186+
def jdbc_driver_library_set?
187+
!@jdbc_driver_library.nil? && !@jdbc_driver_library.empty?
188+
end
162189

190+
def open_jdbc_connection
191+
# at this point driver is already loaded
163192
Sequel.application_timezone = @plugin_timezone.to_sym
164-
if @drivers_loaded.false?
165-
begin
166-
load_driver_jars
167-
Sequel::JDBC.load_driver(@jdbc_driver_class)
168-
rescue LogStash::Error => e
169-
# raised in load_drivers, e.cause should be the caught Java exceptions
170-
raise LogStash::PluginLoadingError, "#{e.message} and #{e.cause.message}"
171-
rescue Sequel::AdapterNotFound => e
172-
# fix this !!!
173-
message = if @jdbc_driver_library.nil?
174-
":jdbc_driver_library is not set, are you sure you included
175-
the proper driver client libraries in your classpath?"
176-
else
177-
"Are you sure you've included the correct jdbc driver in :jdbc_driver_library?"
178-
end
179-
raise LogStash::PluginLoadingError, "#{e}. #{message}"
180-
end
181-
@drivers_loaded.make_true
182-
end
193+
183194
@database = jdbc_connect()
184195
@database.extension(:pagination)
185196
if @jdbc_default_timezone

spec/inputs/jdbc_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,38 @@
12911291
end
12921292
end
12931293

1294+
context "when an unreadable jdbc_driver_path entry is present" do
1295+
let(:driver_jar_path) do
1296+
jar_file = $CLASSPATH.find { |name| name.index(Jdbc::Derby.driver_jar) }
1297+
raise "derby jar not found on class-path" unless jar_file
1298+
jar_file.sub('file:', '')
1299+
end
1300+
1301+
let(:invalid_driver_jar_path) do
1302+
path = File.join(Dir.mktmpdir, File.basename(driver_jar_path))
1303+
FileUtils.cp driver_jar_path, path
1304+
FileUtils.chmod "u=x,go=", path
1305+
path
1306+
end
1307+
1308+
let(:settings) do
1309+
{ "statement" => "SELECT * from types_table", "jdbc_driver_library" => invalid_driver_jar_path }
1310+
end
1311+
1312+
before do
1313+
plugin.register
1314+
end
1315+
1316+
after do
1317+
plugin.stop
1318+
end
1319+
1320+
it "raise a loading error" do
1321+
expect { plugin.run(queue) }.
1322+
to raise_error(LogStash::PluginLoadingError, /unable to load .*? from :jdbc_driver_library, file not readable/)
1323+
end
1324+
end
1325+
12941326
context "when using prepared statements" do
12951327
let(:last_run_value) { 250 }
12961328
let(:expected_queue_size) { 100 }

0 commit comments

Comments
 (0)