Skip to content

Commit cb85a9d

Browse files
committed
Merge branch 'jruby-10.0'
* jruby-10.0: Also make constructor public Make SeekableByteArayChannelImpl public [test] review passing OpenSSL tests [deps] bump jruby-openssl to latest remove redundant test from TestJava.java Fix prepended module initialize not called for Ruby classes rooted in a Java superclass
2 parents 2ba98f8 + 4fd8090 commit cb85a9d

15 files changed

Lines changed: 111 additions & 125 deletions

File tree

core/src/main/java/org/jruby/java/proxies/ConcreteJavaProxy.java

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
201201
}
202202

203203
}
204-
204+
205205
/**
206206
* Manually added as an override of `new` for Concrete Extension
207207
*/
@@ -221,10 +221,12 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
221221
IRubyObject[] args, Block block) {
222222
try {
223223
ConcreteJavaProxy cjp = (ConcreteJavaProxy) self;
224-
// TODO: Insead of selectively overwriting, silently fail? or only use the other method/this method?
224+
// TODO: Instead of selectively overwriting, silently fail? or only use the other method/this method?
225225
if (cjp.getObject() == null) {
226226
withBlock.newInstance(cjp, args, block, context.runtime, clazz);
227227
// note: the generated ctor sets self.object = our discarded return of the new object
228+
} else if (oldInit != null) {
229+
return oldInit.call(context, self, clazz, name, args, block);
228230
}
229231
} catch (InstantiationException | InvocationTargetException e) {
230232
throw JavaProxyConstructor.throwInstantiationExceptionCause(context.runtime, e);
@@ -243,7 +245,7 @@ public static void tryInstall(Ruby runtime, RubyClass clazz, JavaProxyClass prox
243245
// TODO: don't lock in this initialize method
244246
var context = runtime.getCurrentContext();
245247
if (overwriteInitialize) clazz.addMethod(context,"initialize",
246-
new StaticJCreateMethod(clazz, withBlock, clazz.searchMethod("initialize")));
248+
new StaticJCreateMethod(clazz, withBlock, clazz.getMethodLocation().searchMethod("initialize")));
247249
clazz.addMethod(context, "__jallocate!", new StaticJCreateMethod(clazz, withBlock, null));
248250
} catch (SecurityException | NoSuchMethodException e) {
249251
// TODO log?
@@ -321,36 +323,38 @@ public static final class SplitCtorData {
321323
// public fields used by RealClassGenerator's generated code
322324
public final Object[] arguments;
323325
public final int ctorIndex;
324-
326+
325327
// public field used by finishInitialized & (ruby < ruby < java) generated classes
326328
public final IRubyObject[] rbarguments;
327329
public final Block block;
328330

329331
// fields below are only used in ConcreteJavaProxy finishInitialize
330332
private final AbstractIRMethod method;
333+
private final RubyModule clazz;
331334
private final String name;
332335
private final SplitSuperState<?> state;
336+
private final SplitCtorData nested;
333337

334338
/**
335339
* Picks and converts arguments for the super call
336340
* Leaves ctorIndex and arguments ready for the super call
337341
*/
338342
SplitCtorData(Ruby runtime, IRubyObject[] args, JCtorCache cache) {
339-
this(runtime, args, cache, null, null, null, Block.NULL_BLOCK);
343+
this(runtime, args, cache, null, null, null, null, Block.NULL_BLOCK, null);
340344
}
341345

342346
SplitCtorData(Ruby runtime, IRubyObject[] args, JCtorCache cache,
343-
AbstractIRMethod method, SplitSuperState<?> state, Block block) {
344-
this(runtime, args, cache, method, null, state, block);
347+
AbstractIRMethod method, RubyModule clazz, String name, Block block) {
348+
this(runtime, args, cache, method, clazz, name, null, block, null);
345349
}
346350

347351
SplitCtorData(Ruby runtime, IRubyObject[] args, JCtorCache cache,
348-
AbstractIRMethod method, String name, Block block) {
349-
this(runtime, args, cache, method, name, null, block);
352+
AbstractIRMethod method, RubyModule clazz, String name, SplitSuperState<?> state, Block block) {
353+
this(runtime, args, cache, method, clazz, name, state, block, null);
350354
}
351355

352356
private SplitCtorData(Ruby runtime, IRubyObject[] args, JCtorCache cache,
353-
AbstractIRMethod method, String name, SplitSuperState<?> state, Block block) {
357+
AbstractIRMethod method, RubyModule clazz, String name, SplitSuperState<?> state, Block block, SplitCtorData nested) {
354358
rbarguments = args;
355359
if (cache == null) { // (ruby < ruby < java) super call from one IRO to another IRO ctor
356360
ctorIndex = -1;
@@ -361,9 +365,24 @@ private SplitCtorData(Ruby runtime, IRubyObject[] args, JCtorCache cache,
361365
}
362366

363367
this.method = method;
368+
this.clazz = clazz;
369+
this.name = name;
370+
this.state = state;
371+
this.block = block;
372+
this.nested = nested;
373+
}
374+
375+
private SplitCtorData(SplitCtorData ctorData, IRubyObject[] args,
376+
AbstractIRMethod method, RubyModule clazz, String name, SplitSuperState<?> state, Block block) {
377+
this.arguments = ctorData.arguments;
378+
this.ctorIndex = ctorData.ctorIndex;
379+
this.rbarguments = args;
380+
this.method = method;
381+
this.clazz = clazz;
364382
this.name = name;
365383
this.state = state;
366384
this.block = block;
385+
this.nested = ctorData;
367386
}
368387
}
369388

@@ -376,30 +395,57 @@ public SplitCtorData splitInitialized(RubyClass base, IRubyObject[] args, Block
376395
final Ruby runtime = getRuntime();
377396
final String name = base.getClassConfig().javaCtorMethodName;
378397
final CacheEntry methodEntry = base.searchWithCache(name);
398+
final RubyClass sourceLocation = findIncludedPrependedModule(methodEntry.sourceModule, base);
399+
final RubyModule effectiveSource = sourceLocation != null ? sourceLocation : methodEntry.sourceModule;
379400
final boolean isLateral = isClassOrIncludedPrependedModule(methodEntry.sourceModule, base);
380401
DynamicMethod method = methodEntry.method.getRealMethod(); // ensure we don't use a wrapper (jruby/jruby#8148)
381402
if (method instanceof StaticJCreateMethod) method = ((StaticJCreateMethod) method).oldInit;
382403

404+
if (isPrependedJavaCtorWrapper(sourceLocation, base) && method instanceof AbstractIRMethod air) {
405+
SplitSuperState<?> state = air.startSplitSuperCall(runtime.getCurrentContext(), this, effectiveSource, name, args, block);
406+
IRubyObject[] forwardedArgs = state == null ? args : state.callArrayArgs.toJavaArrayMaybeUnsafe();
407+
Block forwardedBlock = state == null ? block : state.callBlockArgs;
408+
SplitCtorData ctorData = splitInitialized(sourceLocation.getSuperClass(), forwardedArgs, forwardedBlock, jcc);
409+
return new SplitCtorData(ctorData, args, air, effectiveSource, name, state, block);
410+
}
411+
383412
// jcreate is for nested ruby classes from a java class
384413
if (isLateral && method instanceof AbstractIRMethod) {
385414

386415
AbstractIRMethod air = (AbstractIRMethod) method; // TODO: getMetaClass() ? or base? (below v)
387416

388-
SplitSuperState<?> state = air.startSplitSuperCall(runtime.getCurrentContext(), this, getMetaClass(), name, args, block);
417+
SplitSuperState<?> state = air.startSplitSuperCall(runtime.getCurrentContext(), this, effectiveSource, name, args, block);
389418
if (state == null) { // no super in method
390-
return new SplitCtorData(runtime, args, jcc, air, name, block);
419+
return new SplitCtorData(runtime, args, jcc, air, effectiveSource, name, block);
391420
}
392-
return new SplitCtorData(runtime, state.callArrayArgs.toJavaArrayMaybeUnsafe(), jcc, air, state, block);
421+
return new SplitCtorData(runtime, state.callArrayArgs.toJavaArrayMaybeUnsafe(), jcc, air, effectiveSource, name, state, block);
393422
}
394423
return new SplitCtorData(runtime, args, jcc);
395424
}
396425

426+
private static boolean isPrependedJavaCtorWrapper(final RubyClass methodSource, final RubyClass klass) {
427+
if (methodSource == null) return false;
428+
429+
return methodSource != klass && methodSource.isIncluded() &&
430+
methodSource.getSuperClass() != null && methodSource.getSuperClass().getDelegate() == klass;
431+
}
432+
433+
private static RubyClass findIncludedPrependedModule(final RubyModule methodSource, final RubyClass klass) {
434+
RubyModule ceiling = klass.getMethodLocation();
435+
436+
for (RubyClass candidate = klass.getSuperClass(); candidate != null && candidate != ceiling; candidate = candidate.getSuperClass()) {
437+
if (candidate.getOrigin() == methodSource.getOrigin()) return candidate;
438+
}
439+
440+
return null;
441+
}
442+
397443
private static boolean isClassOrIncludedPrependedModule(final RubyModule methodSource, final RubyClass klass) {
398-
if (methodSource == klass) return true;
444+
if (methodSource == klass || methodSource.getDelegate() == klass) return true;
399445

400446
RubyClass candidate = klass.getSuperClass();
401447
while (candidate != null && (candidate.isIncluded() || candidate.isPrepended())) { // up till 'real' superclass
402-
if (candidate == klass) return true;
448+
if (candidate == methodSource || candidate.getDelegate() == methodSource.getDelegate()) return true;
403449
candidate = candidate.getSuperClass();
404450
}
405451

@@ -412,11 +458,13 @@ private static boolean isClassOrIncludedPrependedModule(final RubyModule methodS
412458
* <p>Note: invoked from generated byte-code</p>
413459
*/
414460
public void finishInitialize(SplitCtorData returned) {
461+
if (returned.nested != null) finishInitialize(returned.nested);
462+
415463
if (returned.method != null) {
416464
if (returned.state != null) {
417465
returned.method.finishSplitCall(returned.state);
418466
} else { // no super, direct call
419-
returned.method.call(getRuntime().getCurrentContext(), this, getMetaClass(),
467+
returned.method.call(getRuntime().getCurrentContext(), this, returned.clazz,
420468
returned.name, returned.rbarguments, returned.block);
421469
}
422470
}

core/src/main/java/org/jruby/util/io/SeekableByteChannelImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* Seekable byte channel impl over a byte array stream.
2525
* @author kares
2626
*/
27-
final class SeekableByteChannelImpl extends AbstractInterruptibleChannel
27+
public final class SeekableByteChannelImpl extends AbstractInterruptibleChannel
2828
implements ReadableByteChannel, SeekableByteChannel {
2929

3030
private final ByteArrayInputStream in;
@@ -34,7 +34,7 @@ final class SeekableByteChannelImpl extends AbstractInterruptibleChannel
3434

3535
private int truncatedBy = 0;
3636

37-
SeekableByteChannelImpl(ByteArrayInputStream in) {
37+
public SeekableByteChannelImpl(ByteArrayInputStream in) {
3838
this.in = in;
3939
this.mark = mark(in);
4040
this.count = count(in);

lib/pom.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def log(message = nil)
5050
['ipaddr', '1.2.8'],
5151
['jar-dependencies', '0.5.7'],
5252
['jruby-readline', '1.3.7'],
53-
['jruby-openssl', '0.15.5'],
53+
['jruby-openssl', '0.15.6'],
5454
['json', '2.18.0'],
5555
['net-http', '0.9.1'],
5656
['net-protocol', '0.2.2'],

lib/pom.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ DO NOT MODIFY - GENERATED CODE
281281
<dependency>
282282
<groupId>rubygems</groupId>
283283
<artifactId>jruby-openssl</artifactId>
284-
<version>0.15.5</version>
284+
<version>0.15.6</version>
285285
<type>gem</type>
286286
<scope>provided</scope>
287287
<exclusions>
@@ -1163,7 +1163,7 @@ DO NOT MODIFY - GENERATED CODE
11631163
<include>specifications/ipaddr-1.2.8*</include>
11641164
<include>specifications/jar-dependencies-0.5.7*</include>
11651165
<include>specifications/jruby-readline-1.3.7*</include>
1166-
<include>specifications/jruby-openssl-0.15.5*</include>
1166+
<include>specifications/jruby-openssl-0.15.6*</include>
11671167
<include>specifications/json-2.18.0*</include>
11681168
<include>specifications/net-http-0.9.1*</include>
11691169
<include>specifications/net-protocol-0.2.2*</include>
@@ -1247,7 +1247,7 @@ DO NOT MODIFY - GENERATED CODE
12471247
<include>gems/ipaddr-1.2.8*/**/*</include>
12481248
<include>gems/jar-dependencies-0.5.7*/**/*</include>
12491249
<include>gems/jruby-readline-1.3.7*/**/*</include>
1250-
<include>gems/jruby-openssl-0.15.5*/**/*</include>
1250+
<include>gems/jruby-openssl-0.15.6*/**/*</include>
12511251
<include>gems/json-2.18.0*/**/*</include>
12521252
<include>gems/net-http-0.9.1*/**/*</include>
12531253
<include>gems/net-protocol-0.2.2*/**/*</include>
@@ -1331,7 +1331,7 @@ DO NOT MODIFY - GENERATED CODE
13311331
<include>cache/ipaddr-1.2.8*</include>
13321332
<include>cache/jar-dependencies-0.5.7*</include>
13331333
<include>cache/jruby-readline-1.3.7*</include>
1334-
<include>cache/jruby-openssl-0.15.5*</include>
1334+
<include>cache/jruby-openssl-0.15.6*</include>
13351335
<include>cache/json-2.18.0*</include>
13361336
<include>cache/net-http-0.9.1*</include>
13371337
<include>cache/net-protocol-0.2.2*</include>
@@ -1415,7 +1415,7 @@ DO NOT MODIFY - GENERATED CODE
14151415
<include>extensions/universal-java/4.0.0/ipaddr-1.2.8/*</include>
14161416
<include>extensions/universal-java/4.0.0/jar-dependencies-0.5.7/*</include>
14171417
<include>extensions/universal-java/4.0.0/jruby-readline-1.3.7/*</include>
1418-
<include>extensions/universal-java/4.0.0/jruby-openssl-0.15.5/*</include>
1418+
<include>extensions/universal-java/4.0.0/jruby-openssl-0.15.6/*</include>
14191419
<include>extensions/universal-java/4.0.0/json-2.18.0/*</include>
14201420
<include>extensions/universal-java/4.0.0/net-http-0.9.1/*</include>
14211421
<include>extensions/universal-java/4.0.0/net-protocol-0.2.2/*</include>

spec/java_integration/reify/become_java_spec.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,42 @@ class TopRightOfTheJStack < MiddleOfTheJStack ;def size; super + 3; end ; end
120120
expect(TopRightOfTheJStack.new([:a, :b]).size).to eq (2+3)
121121
end
122122

123+
it "calls prepended and leaf initialize methods for Ruby classes rooted in a Java superclass" do
124+
class PrependJavaBaseInitC < java.util.ArrayList
125+
def initialize(trace)
126+
trace << :c
127+
super()
128+
end
129+
end
130+
131+
class PrependJavaBaseInitD < PrependJavaBaseInitC
132+
def initialize(trace)
133+
trace << :d
134+
super
135+
end
136+
end
137+
138+
class PrependJavaBaseInitE < PrependJavaBaseInitD
139+
def initialize(trace)
140+
trace << :e
141+
super
142+
end
143+
end
144+
145+
module PrependJavaBaseInitM
146+
def initialize(trace)
147+
trace << :m
148+
super
149+
end
150+
end
151+
152+
PrependJavaBaseInitE.prepend(PrependJavaBaseInitM)
153+
154+
trace = []
155+
PrependJavaBaseInitE.new(trace)
156+
expect(trace).to eq([:m, :e, :d, :c])
157+
end
158+
123159
it "supports auto reifying a class hierarchy when class gets redefined" do
124160
class ASubList < java.util.ArrayList
125161
attr_reader :args
Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,10 @@
11
exclude :test_basic_asn1data, "work in progress"
22
exclude :test_basic_constructed, "work in progress"
3-
exclude :test_basic_primitive, "work in progress"
4-
exclude :test_bit_string_infinite_length, 'encoding works but decoding not implemented'
5-
exclude :test_bitstring, "work in progress"
6-
exclude :test_cons_explicit_tagging, 'needs investigation'
7-
exclude :test_cons_implicit_tagging, 'needs investigation'
8-
exclude :test_cons_without_array_forbidden, 'needs investigation'
9-
exclude :test_create_inf_length_primitive, 'needs investigation'
103
exclude :test_decode_constructed_overread, "work in progress"
11-
exclude :test_decode_x509_certificate, "work in progress"
124
exclude :test_end_of_content, "work in progress"
135
exclude :test_generalizedtime, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271"
146
exclude :test_object_identifier, "work in progress"
15-
exclude :test_octet_string_constructed_tagging, "work in progress"
16-
exclude :test_octet_string_infinite_length_explicit_tagging, 'needs investigation'
17-
exclude :test_octet_string_infinite_length_implicit_tagging, 'needs investigation'
18-
exclude :test_prim_implicit_tagging, 'needs investigation'
197
exclude :test_recursive_octet_string_indefinite_length, "work in progress"
20-
exclude :test_recursive_octet_string_infinite_length, 'needs investigation'
21-
exclude :test_recursive_octet_string_parse, 'needs investigation'
8+
exclude :test_recursive_octet_string_parse, "work in progress"
229
exclude :test_sequence, "work in progress"
2310
exclude :test_set, "work in progress"
24-
exclude :test_string_basic, "work in progress"
25-
exclude :test_utctime, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271"

test/mri/excludes/OpenSSL/TestCipher.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
exclude :test_AES, 'works - just need to enable JCE unlimited strength'
2-
exclude :test_AES_crush, 'needs investigation'
31
exclude :test_aes_gcm, "work in progress"
42
exclude :test_auth_tag_error_inheritance, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271"
53
exclude :test_ciphers, "work in progress"
Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
exclude :test_ECPrivateKey, "work in progress"
2-
exclude :test_ECPrivateKey_encrypted, "work in progress"
3-
exclude :test_PUBKEY, "work in progress"
41
exclude :test_check_key, "work in progress"
5-
exclude :test_derive_key, "TODO: OpenSSL::PKey::EC#derive not yet implemented"
6-
exclude :test_dh_compute_key, "work in progress"
7-
exclude :test_dsa_sign_asn1_FIPS186_3, "work in progress"
8-
exclude :test_ec_group, "work in progress"
9-
exclude :test_ec_key, "work in progress"
10-
exclude :test_ec_key_new, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, private key as well as public key are null"
11-
exclude :test_ec_key_new_empty, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, null curve name"
122
exclude :test_ec_point, "work in progress"
133
exclude :test_ec_point_add, "work in progress"
144
exclude :test_ec_point_mul, "work in progress"
15-
exclude :test_generate, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271"
16-
exclude :test_generate_key, "work in progress"
175
exclude :test_sign_verify_raw, "work in progress"
186
exclude :test_small_curve, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, null curve name"

test/mri/excludes/OpenSSL/TestPKey.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,3 @@
88
exclude :test_s_generate_key, "work in progress"
99
exclude :test_s_generate_parameters, "work in progress"
1010
exclude :test_s_generate_parameters_with_block, "work in progress"
11-
exclude :test_s_read_der_then_pem, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, undefined method 'private_to_pem' for an instance of OpenSSL::PKey::RSA"
12-
exclude :test_s_read_passphrase, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, undefined method 'private_to_pem' for an instance of OpenSSL::PKey::RSA"
13-
exclude :test_s_read_pem_unknown_block, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, undefined method 'private_to_pem' for an instance of OpenSSL::PKey::RSA"
14-
exclude :test_x25519, "work in progress"

test/mri/excludes/OpenSSL/TestPKeyDSA.rb

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,5 @@
22
exclude :test_DSAPrivateKey_encrypted, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, IllegalArgumentException: Bad sequence size: 3"
33
exclude :test_PUBKEY, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, IllegalArgumentException: Bad sequence size: 3"
44
exclude :test_dup, 'passes except for setting (invalid) `key2.p + 1` as validation happens early'
5-
exclude :test_export_password_length, 'needs investigation'
6-
exclude :test_marshal, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, IllegalArgumentException: Bad sequence size: 3"
75
exclude :test_new_break, 'needs investigation'
8-
exclude :test_new_empty, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271"
9-
exclude :test_params, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, IllegalArgumentException: Bad sequence size: 3"
10-
exclude :test_private, "new failure with Ruby 4.0 tests, tested on MacOS, https://github.com/jruby/jruby/issues/9271, IllegalArgumentException: Bad sequence size: 3"
11-
exclude :test_sign_verify, "work in progress"
12-
exclude :test_sign_verify_raw, "TODO: sign_raw not implemented"
6+
exclude :test_sign_verify_raw, "work in progress"

0 commit comments

Comments
 (0)