hbase-jruby 0.1.6-java → 0.2.0-java

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 0.2.0
5
+ -----
6
+ - Deprecated `HBase::Table#close`. You don't need to close Table instances.
7
+ - Added `HBase::Table#split` and `HBase::Table#split!` method
8
+ - Added `:splits` option to `HTable#create!` method to pre-split the table
9
+ - Added table inspection methods: `properties`, `families`, and `regions`
10
+ - Added raw inspection methods: `raw_properties` and `raw_families`
11
+ - Added `HBase.log4j=` method
12
+ - Added `HBase::Scoped#at`, `HBase::Scoped#time_range` method
13
+ - Changed parameters to `HBase.resolve_dependency!` method
14
+ - Ruby Time object can be used as timestamp in put and delete methods
15
+ - Using closed HBase connection is disallowed
16
+ - Ruby 1.8 compatibility mode (Oops!)
17
+
4
18
  0.1.6
5
19
  -----
6
20
  - Maven dependencies for 0.94 and 0.92
data/README.md CHANGED
@@ -20,7 +20,7 @@ require 'hbase-jruby'
20
20
  HBase.resolve_dependency! 'cdh4.1'
21
21
 
22
22
  hbase = HBase.new
23
- table = hbase.table(:test_table)
23
+ table = hbase[:test_table]
24
24
 
25
25
  # PUT
26
26
  table.put :rowkey1 => { 'cf1:a' => 100, 'cf2:b' => "Hello" }
@@ -56,7 +56,7 @@ table.delete(:rowkey9)
56
56
  git clone -b devel https://github.com/junegunn/hbase-jruby.git
57
57
  cd hbase-jruby
58
58
  rake build
59
- gem install pkg/hbase-jruby-0.1.6-java.gem
59
+ gem install pkg/hbase-jruby-0.2.0-java.gem
60
60
 
61
61
  ## Setting up
62
62
 
@@ -65,47 +65,51 @@ table.delete(:rowkey9)
65
65
  To be able to access HBase from JRuby, Hadoop/HBase dependency must be satisfied.
66
66
  This can be done by either setting up CLASSPATH variable beforehand
67
67
  or by `require`ing relevant JAR files after launching JRuby.
68
- However, that's a lot of work, so *hbase-jruby* provides `HBase.resolve_dependency!` helper method,
69
- which automatically resolves Hadoop/HBase dependency.
70
68
 
71
- #### Preconfigured dependencies
69
+ ### `HBase.resolve_dependency!`
72
70
 
73
- Apache Maven is the de facto standard dependency management mechanism for Java projects.
74
- Current version of *hbase-jruby* is shipped with
75
- [Maven dependency specifications](https://github.com/junegunn/hbase-jruby/blob/master/lib/hbase-jruby/pom/pom.xml)
76
- for the following Hadoop/HBase distributions.
71
+ Well, there's an easier way.
72
+ You can call `HBase.resolve_dependency!` helper method passing one of the arguments listed below.
77
73
 
78
- * cdh4.1
79
- * cdh3
80
- * 0.94
81
- * 0.92
74
+ | Argument | Description | Required executable |
75
+ |------------|----------------------------------------------------------|---------------------|
76
+ | 'cdh4.1' | Predefined Maven profile for Cloudera CDH4.1 | mvn |
77
+ | 'cdh3' | Predefined Maven profile for Cloudera CDH3 | mvn |
78
+ | '0.94' | Predefined Maven profile for Apache HBase 0.94 | mvn |
79
+ | '0.92' | Predefined Maven profile for Apache HBase 0.92 | mvn |
80
+ | *POM PATH* | Follow dependency described in the given POM file | mvn |
81
+ | *:local* | Resolve HBase dependency using `hbase classpath` command | hbase |
82
82
 
83
83
  ```ruby
84
- require 'hbase-jruby'
84
+ # Examples
85
85
 
86
+ # Load JAR files from CDH4.1 distribution of HBase using Maven
86
87
  HBase.resolve_dependency! 'cdh4.1'
88
+
89
+ # Load JAR files for HBase 0.94 using Maven
90
+ HBase.resolve_dependency! '0.94', :verbose => true
91
+
92
+ # Dependency resolution with your own POM file
93
+ HBase.resolve_dependency! '/path/to/my/pom.xml'
94
+ HBase.resolve_dependency! '/path/to/my/pom.xml', :profile => 'trunk'
95
+
96
+ # Resolve JAR files from local HBase installation
97
+ HBase.resolve_dependency! :local
87
98
  ```
88
99
 
89
100
  (If you're behind an http proxy, set up your ~/.m2/settings.xml file
90
101
  as described in [this page](http://maven.apache.org/guides/mini/guide-proxies.html))
91
102
 
92
- #### Custom dependency
103
+ ### Log4j logs from HBase
93
104
 
94
- If you use other versions of HBase and Hadoop,
95
- you can use your own Maven pom.xml file with its Hadoop/HBase dependency.
105
+ You may want to suppress (or customize) log messages from HBase.
96
106
 
97
107
  ```ruby
98
- HBase.resolve_dependency! '/project/my-hbase/pom.xml'
99
- ```
100
-
101
- #### Using `hbase classpath` command
108
+ # With an external log4j.properties file
109
+ HBase.log4j = '/your/log4j.properties'
102
110
 
103
- If you have HBase installed on your system, it's possible to locate the JAR files
104
- for that local installation with `hbase classpath` command.
105
- You can tell `resolve_dependency!` method to do so by passing it special `:hbase` parameter.
106
-
107
- ```ruby
108
- HBase.resolve_dependency! :hbase
111
+ # With a Hash
112
+ HBase.log4j = { 'log4j.threshold' => 'ERROR' }
109
113
  ```
110
114
 
111
115
  ### Connecting to HBase
@@ -129,30 +133,23 @@ hbase.close
129
133
 
130
134
  ## Accessing data with HBase::Table instance
131
135
 
132
- `HBase#table` method creates an `HBase::Table` instance which represents a table on HBase.
136
+ `HBase#[]` method (or `HBase#table`) returns an `HBase::Table` instance
137
+ which represents the table of the given name.
133
138
 
134
139
  ```ruby
135
140
  table = hbase.table(:test_table)
136
- ```
137
-
138
- `HBase::Table` instance must be closed after use.
139
141
 
140
- ```ruby
141
- # Always close table instance after use
142
- table.close
143
-
144
- # If block is given, table is automatically closed at the end of the block
145
- hbase.table(:test_table) do |table|
146
- # ...
147
- end
142
+ # Or simply,
143
+ table = hbase[:test_table]
148
144
  ```
149
145
 
146
+
150
147
  ## Basic table administration
151
148
 
152
- ### Creating tables
149
+ ### Creating a table
153
150
 
154
151
  ```ruby
155
- table = hbase.table(:my_table)
152
+ table = hbase[:my_table]
156
153
 
157
154
  # Drop table if exists
158
155
  table.drop! if table.exists?
@@ -165,7 +162,75 @@ table.create! :cf1 => {},
165
162
  ### Table inspection
166
163
 
167
164
  ```ruby
168
- puts table.inspect
165
+ # Table properties
166
+ table.properties
167
+ # {:max_filesize => 2147483648,
168
+ # :readonly => false,
169
+ # :memstore_flushsize => 134217728,
170
+ # :deferred_log_flush => false}
171
+
172
+ # Properties of the column families
173
+ table.families
174
+ # {"cf"=>
175
+ # {:blockcache => true,
176
+ # :blocksize => 65536,
177
+ # :bloomfilter => "NONE",
178
+ # :cache_blooms_on_write => false,
179
+ # :cache_data_on_write => false,
180
+ # :cache_index_on_write => false,
181
+ # :compression => "NONE",
182
+ # :compression_compact => "NONE",
183
+ # :data_block_encoding => "NONE",
184
+ # :evict_blocks_on_close => false,
185
+ # :in_memory => false,
186
+ # :keep_deleted_cells => false,
187
+ # :min_versions => 0,
188
+ # :replication_scope => 0,
189
+ # :ttl => 2147483647,
190
+ # :versions => 3}}
191
+ ```
192
+
193
+ There are also `raw_` variants of `properties` and `families`.
194
+ They return properties in their internal String format (mainly used in HBase shell).
195
+ (See [HTableDescriptor.values](http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/HTableDescriptor.html#values) and
196
+ [HColumnDescriptor.values](http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/HColumnDescriptor.html#values))
197
+
198
+ ```ruby
199
+ table.raw_properties
200
+ # {"IS_ROOT" => "false",
201
+ # "IS_META" => "false",
202
+ # "MAX_FILESIZE" => "2147483648"}
203
+
204
+ table.raw_families
205
+ # {"cf" =>
206
+ # {"DATA_BLOCK_ENCODING" => "NONE",
207
+ # "BLOOMFILTER" => "NONE",
208
+ # "REPLICATION_SCOPE" => "0",
209
+ # "VERSIONS" => "3",
210
+ # "COMPRESSION" => "NONE",
211
+ # "MIN_VERSIONS" => "0",
212
+ # "TTL" => "2147483647",
213
+ # "KEEP_DELETED_CELLS" => "false",
214
+ # "BLOCKSIZE" => "65536",
215
+ # "IN_MEMORY" => "false",
216
+ # "ENCODE_ON_DISK" => "true",
217
+ # "BLOCKCACHE" => "true"}}
218
+ ```
219
+
220
+ These String key-value pairs are not really a part of the public API of HBase, and thus might change over time.
221
+ However, they are most useful when you need to create a table with the same properties as the existing one.
222
+
223
+ ```ruby
224
+ hbase[:dupe_table].create!(table.raw_families, table.raw_properties)
225
+ ```
226
+
227
+ With `regions` method, you can even presplit the new table just like the old one.
228
+
229
+ ```ruby
230
+ hbase[:dupe_table].create!(
231
+ table.raw_families,
232
+ table.raw_properties.merge(
233
+ :splits => table.regions.map { |r| r[:start_key] }.compact))
169
234
  ```
170
235
 
171
236
  ## Basic operations
@@ -333,52 +398,59 @@ table.increment('rowkey1', 'cf1:counter' => 1, 'cf1:counter2' => 2)
333
398
  ```ruby
334
399
  # Full scan
335
400
  table.each do |row|
401
+ age = row.fixnum('cf:age')
402
+ name = row.string('cf:name')
336
403
  # ...
337
404
  end
338
405
  ```
339
406
 
340
407
  ## Scoped access
341
408
 
342
- SCAN and GET operations are actually implemented in enumerable `HBase::Scoped` class,
343
- whose instance is created by `HBase::Table#each` call.
344
-
345
- ```ruby
346
- scoped = table.each
347
- scoped.get(1)
348
- scoped.to_a
349
- ```
409
+ You can control how you retrieve data by chaining
410
+ the following methods of `HBase::Table` (or `HBase::Scoped`).
350
411
 
351
- An `HBase::Scoped` object provides a set of methods for controlling data retrieval
352
- such as `range`, `filter`, `project`, `versions`, `caching`, et cetera.
353
- However, it doesn't respond to data manipulation methods (`put`, `delete` and `increment`),
354
- and methods for table administration.
412
+ | Method | Description |
413
+ |--------------|-----------------------------------------------------------------|
414
+ | `range` | Specifies the rowkey range of scan |
415
+ | `project` | To retrieve only a subset of columns |
416
+ | `filter` | Filtering conditions of scan |
417
+ | `while` | Allows early termination of scan (server-side) |
418
+ | `at` | Only retrieve data with the specified timestamp |
419
+ | `time_range` | Only retrieve data within the specified time range |
420
+ | `limit` | Limits the number of rows |
421
+ | `versions` | Limits the number of versions of each column |
422
+ | `caching` | Sets the number of rows for caching during scan |
423
+ | `batch` | Limits the maximum number of values returned for each iteration |
355
424
 
356
- An `HBase::Table` object also responds to the data retrieval methods described above,
357
- but those calls are simply forwarded to a new `HBase::Scoped` object implicitly created.
358
- For example, `table.range(start, end)` is just a shorthand notation for
359
- `table.each.range(start, end)`.
425
+ Each invocation to these methods returns an `HBase::Scoped` instance with which
426
+ you can retrieve data with the following methods.
360
427
 
361
- ### Chaining methods
428
+ | Method | Description |
429
+ |-------------|-------------------------------------------------------------------------|
430
+ | `get` | Fetches rows by the given rowkeys |
431
+ | `each` | Scans the scope of the table (`HBase::Scoped` instance is `Enumerable`) |
432
+ | `count` | Efficiently counts the number of rows in the scope |
433
+ | `aggregate` | Performs aggregation using Coprocessor (To be described shortly) |
362
434
 
363
- Methods of `HBase::Scoped` can be chained as follows.
435
+ ### Example of scoped access
364
436
 
365
437
  ```ruby
366
- # Chaining methods
367
438
  import org.apache.hadoop.hbase.filter.RandomRowFilter
368
439
 
369
- table.range('A'..'Z'). # Row key range,
370
- project('cf1:a'). # Select cf1:a column
371
- project('cf2'). # Select cf2 family as well
372
- filter('cf1:a' => 'Hello'). # Filter by cf1:a value
373
- filter('cf2:d' => 100..200). # Range filter on cf2:d
374
- filter('cf2:e' => [10, 20..30]). # Set-inclusion condition on cf2:e
375
- filter(RandomRowFilter.new(0.5)). # Any Java HBase filter
376
- while('cf2:f' => { ne: 'OPEN' }). # Early termination of scan
377
- limit(10). # Limits the size of the result set
378
- versions(2). # Only fetches 2 versions for each value
379
- batch(100). # Batch size for scan set to 100
380
- caching(100). # Caching 100 rows
381
- to_a # To Array
440
+ table.range('A'..'Z'). # Row key range,
441
+ project('cf1:a'). # Select cf1:a column
442
+ project('cf2'). # Select cf2 family as well
443
+ filter('cf1:a' => 'Hello'). # Filter by cf1:a value
444
+ filter('cf2:d' => 100..200). # Range filter on cf2:d
445
+ filter('cf2:e' => [10, 20..30]). # Set-inclusion condition on cf2:e
446
+ filter(RandomRowFilter.new(0.5)). # Any Java HBase filter
447
+ while('cf2:f' => { ne: 'OPEN' }). # Early termination of scan
448
+ time_range(Time.now - 600, Time.now). # Scan data of the last 10 minutes
449
+ limit(10). # Limits the size of the result set
450
+ versions(2). # Only fetches 2 versions for each value
451
+ batch(100). # Batch size for scan set to 100
452
+ caching(1000). # Caching 1000 rows
453
+ to_a # To Array
382
454
  ```
383
455
 
384
456
  ### *range*
@@ -570,7 +642,7 @@ end
570
642
  scoped.count
571
643
 
572
644
  # This should be even faster as it dramatically reduces the number of RPC calls
573
- scoped.caching(1000).count
645
+ scoped.caching(5000).count
574
646
  ```
575
647
 
576
648
  ## Basic aggregation using coprocessor
@@ -728,30 +800,28 @@ ba.java # Returns the native Java byte array (byte[])
728
800
 
729
801
  ### Table administration
730
802
 
731
- `HBase#Table` provides a few synchronous (`HTable#method_name!`) and
732
- asynchronous (`HTable#method_name`) table administration methods.
733
- Synchronous *bang* methods for table alteration take an optional block and pass the progress of the operation to it
734
- as a pair of parameters, the number of regions processed and total number of regions to process.
803
+ `HBase#Table` provides a number of *bang_methods!* for table administration tasks.
804
+ They run synchronously, except when mentioned otherwise (e.g. `HTable#split!`).
805
+ Some of them take an optional block to allow progress monitoring
806
+ and come with non-bang, asynchronous counterparts.
807
+
808
+ #### Creation and alteration
735
809
 
736
810
  ```ruby
737
811
  # Create a table with configurable table-level properties
738
812
  table.create!(
739
813
  # 1st Hash: Column family specification
740
- { :cf1 => { :compression => :snappy }, :cf2 => {} },
814
+ {
815
+ :cf1 => { :compression => :snappy },
816
+ :cf2 => { :bloomfilter => :row }
817
+ },
741
818
 
742
819
  # 2nd Hash: Table properties
743
820
  :max_filesize => 256 * 1024 ** 2,
744
- :deferred_log_flush => false)
821
+ :deferred_log_flush => false,
822
+ :splits => [1000, 2000, 3000])
745
823
 
746
- # Alter table properties (asynchronous)
747
- table.alter(
748
- :max_filesize => 512 * 1024 ** 2,
749
- :memstore_flushsize => 64 * 1024 ** 2,
750
- :readonly => false,
751
- :deferred_log_flush => true
752
- )
753
-
754
- # Alter table properties (synchronous)
824
+ # Alter table properties (synchronous with optional block)
755
825
  table.alter!(
756
826
  :max_filesize => 512 * 1024 ** 2,
757
827
  :memstore_flushsize => 64 * 1024 ** 2,
@@ -762,6 +832,56 @@ table.alter!(
762
832
  puts [progress, total].join('/')
763
833
  }
764
834
 
835
+ # Alter table properties (asynchronous)
836
+ table.alter(
837
+ :max_filesize => 512 * 1024 ** 2,
838
+ :memstore_flushsize => 64 * 1024 ** 2,
839
+ :readonly => false,
840
+ :deferred_log_flush => true
841
+ )
842
+ ```
843
+
844
+ ##### List of column family properties
845
+
846
+ http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/HColumnDescriptor.html
847
+
848
+ Some of the properties are only available on recent versions of HBase.
849
+
850
+ | Property | Type | Description |
851
+ |--------------------------|---------------|--------------------------------------------------------------------------------------------------------------------|
852
+ | `:blockcache` | Boolean | If MapFile blocks should be cached |
853
+ | `:blocksize` | Fixnum | Blocksize to use when writing out storefiles/hfiles on this column family |
854
+ | `:bloomfilter` | Symbol/String | Bloom filter type: `:none`, `:row`, `:rowcol`, or uppercase Strings |
855
+ | `:cache_blooms_on_write` | Boolean | If we should cache bloomfilter blocks on write |
856
+ | `:cache_data_on_write` | Boolean | If we should cache data blocks on write |
857
+ | `:cache_index_on_write` | Boolean | If we should cache index blocks on write |
858
+ | `:compression` | Symbol/String | Compression type: `:none`, `:gz`, `:lzo`, `:lz4`, `:snappy`, or uppercase Strings |
859
+ | `:compression_compact` | Symbol/String | Compression type: `:none`, `:gz`, `:lzo`, `:lz4`, `:snappy`, or uppercase Strings |
860
+ | `:data_block_encoding` | Symbol/String | Data block encoding algorithm used in block cache: `:none`, `:diff`, `:fast_diff`, `:prefix`, or uppercase Strings |
861
+ | `:encode_on_disk` | Boolean | If we want to encode data block in cache and on disk |
862
+ | `:evict_blocks_on_close` | Boolean | If we should evict cached blocks from the blockcache on close |
863
+ | `:in_memory` | Boolean | If we are to keep all values in the HRegionServer cache |
864
+ | `:keep_deleted_cells` | Boolean | If deleted rows should not be collected immediately |
865
+ | `:min_versions` | Fixnum | The minimum number of versions to keep (used when timeToLive is set) |
866
+ | `:replication_scope` | Fixnum | Replication scope |
867
+ | `:ttl` | Fixnum | Time-to-live of cell contents, in seconds |
868
+ | `:versions` | Fixnum | The maximum number of versions. (By default, all available versions are retrieved.) |
869
+
870
+ ##### List of table properties
871
+
872
+ http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/HTableDescriptor.html
873
+
874
+ | Property | Type | Description |
875
+ |-----------------------|---------|---------------------------------------------------------------------------------------------------------|
876
+ | `:max_filesize` | Fixnum | The maximum size upto which a region can grow to after which a region split is triggered |
877
+ | `:readonly` | Boolean | If the table is read-only |
878
+ | `:memstore_flushsize` | Fixnum | The maximum size of the memstore after which the contents of the memstore are flushed to the filesystem |
879
+ | `:deferred_log_flush` | Boolean | Defer the log edits syncing to the file system |
880
+ | `:splits` | Array | Region split points |
881
+
882
+ #### Managing column families
883
+
884
+ ```ruby
765
885
  # Add column family
766
886
  table.add_family! :cf3, :compression => :snappy,
767
887
  :bloomfilter => :row
@@ -771,7 +891,11 @@ table.alter_family! :cf2, :bloomfilter => :rowcol
771
891
 
772
892
  # Remove column family
773
893
  table.delete_family! :cf1
894
+ ```
774
895
 
896
+ #### Coprocessors
897
+
898
+ ```ruby
775
899
  # Add Coprocessor
776
900
  unless table.has_coprocessor?(cp_class_name1)
777
901
  table.add_coprocessor! cp_class_name1
@@ -783,14 +907,21 @@ table.add_coprocessor! cp_class_name2,
783
907
  table.remove_coprocessor! cp_class_name1
784
908
  ```
785
909
 
910
+ #### Region splits (asynchronous)
911
+
912
+ ```ruby
913
+ table.split!(1000)
914
+ table.split!(2000, 3000)
915
+ ```
916
+
917
+ #### Advanced table administration
918
+
786
919
  You can perform other types of administrative tasks
787
920
  with native Java [HBaseAdmin object](http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/HBaseAdmin.html),
788
921
  which can be obtained by `HBase#admin` method. Optionally, a block can be given
789
922
  so that the HBaseAdmin object is automatically closed at the end of the given block.
790
923
 
791
924
  ```ruby
792
- # Advanced table administration with HBaseAdmin object
793
- # http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/HBaseAdmin.html
794
925
  admin = hbase.admin
795
926
  # ...
796
927
  admin.close
@@ -804,8 +935,10 @@ end
804
935
  ## Test
805
936
 
806
937
  ```bash
807
- # Bash script
808
- export HBASE_JRUBY_TEST_ZK='your-hbaase.domain.net'
938
+ #!/bin/bash
939
+
940
+ # Test HBase 0.94 on localhost
941
+ export HBASE_JRUBY_TEST_ZK='127.0.0.1'
809
942
  export HBASE_JRUBY_TEST_DIST='0.94'
810
943
 
811
944
  # Test both for 1.8 and 1.9
@@ -3,6 +3,8 @@ class HBase
3
3
  module Admin
4
4
  private
5
5
  def with_admin
6
+ check_closed
7
+
6
8
  begin
7
9
  admin = HBaseAdmin.new(@config)
8
10
  yield admin
@@ -19,7 +21,7 @@ private
19
21
  total = pair.getSecond
20
22
 
21
23
  if block && yet != prev_yet
22
- block.call (total - yet), total
24
+ block.call(total - yet, total)
23
25
  prev_yet = yet
24
26
  end
25
27
 
@@ -5,26 +5,44 @@ require 'tempfile'
5
5
  # HBase connection
6
6
  class HBase
7
7
  class << self
8
- # Resolve Hadoop and HBase dependency with Maven or hbase command (Experimental)
9
- # @param [String] dist Distribution version or path to pom.xml file
10
- # @param [true, false] verbose Verbose output
11
- # @return [Array<String>] Loaded JAR files
12
- def resolve_dependency! dist, verbose = false
8
+ # @overload resolve_dependency!(dist, options)
9
+ # Resolve Hadoop and HBase dependency with a predefined Maven profile
10
+ # @param [String] dist HBase distribution: cdh4.1, cdh3, 0.94, 0.92, local
11
+ # @param [Hash] options Options
12
+ # @option options [Boolean] :verbose Enable verbose output
13
+ # @return [Array<String>] Loaded JAR files
14
+ # @overload resolve_dependency!(pom_path, options)
15
+ # Resolve Hadoop and HBase dependency with the given Maven POM file
16
+ # @param [String] pom_path Path to POM file
17
+ # @param [Hash] options Options
18
+ # @option options [Boolean] :verbose Enable verbose output
19
+ # @option options [String] :profile Maven profile
20
+ # @return [Array<String>] Loaded JAR files
21
+ def resolve_dependency! dist, options = {}
22
+ # Backward-compatibility
23
+ options = { :verbose => options } if [true, false].include?(options)
24
+ options = { :verbose => false }.merge(options)
25
+
26
+ dist = dist.to_s
27
+ verbose = options[:verbose]
28
+
13
29
  silencer = verbose ? '' : '> /dev/null'
14
30
  tempfiles = []
31
+
15
32
  jars =
16
- if dist == :hbase
33
+ if %w[hbase local].include?(dist)
17
34
  # Check for hbase executable
18
35
  hbase = `which hbase`
19
- raise RuntimeError, "Cannot find executable `hbase`" if hbase.empty?
36
+ raise RuntimeError, "Cannot find `hbase` executable" if hbase.empty?
20
37
  `hbase classpath`.split(':')
21
38
  else
22
39
  # Check for Maven executable
23
40
  mvn = `which mvn`
24
- raise RuntimeError, "Cannot find executable `mvn`" if mvn.empty?
41
+ raise RuntimeError, "Cannot find `mvn` executable" if mvn.empty?
25
42
 
26
43
  if File.exists?(dist)
27
44
  path = dist
45
+ profile = options[:profile] && "-P #{options[:profile]}"
28
46
  else
29
47
  path = File.expand_path("../pom/pom.xml", __FILE__)
30
48
  profile = "-P #{dist}"
@@ -35,10 +53,17 @@ class HBase
35
53
  tf.close(false)
36
54
  system "mvn org.apache.maven.plugins:maven-dependency-plugin:2.5.1:resolve org.apache.maven.plugins:maven-dependency-plugin:2.5.1:build-classpath -Dsilent=true -Dmdep.outputFile=#{tf.path} #{profile} -f #{path} #{silencer}"
37
55
 
38
- raise RuntimeError.new("Error occurred. Set verbose parameter to see the log.") unless $?.exitstatus == 0
56
+ raise RuntimeError.new("Error occurred. Set verbose option to see the log.") unless $?.exitstatus == 0
39
57
 
40
- output = File.read(tf.path)
41
- raise ArgumentError.new("Invalid profile: #{dist}") if output.empty?
58
+ if File.read(tf.path).empty?
59
+ desc =
60
+ if options[:profile]
61
+ "#{dist} (#{options[:profile]})"
62
+ else
63
+ dist
64
+ end
65
+ raise ArgumentError.new("Invalid profile: #{desc}")
66
+ end
42
67
  File.read(tf.path).split(':')
43
68
  end
44
69
 
@@ -68,7 +93,7 @@ class HBase
68
93
  base.class_eval do
69
94
  classes.map { |klass|
70
95
  begin
71
- import klass
96
+ java_import klass
72
97
  nil
73
98
  rescue NameError => e
74
99
  klass