Fix separate issues in JRuby's "native" `dup` and `inspect` methods. (#15265)

Update the stress test to exercise `proto3_optional` fields.

Closes #15265

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/15265 from protocolbuffers:fix_jruby_proto3_optional 4040e13a7bc1c183b7e57073f070ea13518122c0
PiperOrigin-RevId: 596028361
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
index 365f23c..25d169b 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
@@ -203,7 +203,7 @@
     sb.append(cname).append(colon);
 
     for (FieldDescriptor fd : descriptor.getFields()) {
-      if (fd.hasPresence() && !fields.containsKey(fd)) {
+      if (fd.hasPresence() && !(fields.containsKey(fd) || builder.hasField(fd))) {
         continue;
       }
       if (addComma) {
@@ -551,7 +551,8 @@
       } else if (fields.containsKey(fieldDescriptor)) {
         dup.setFieldInternal(context, fieldDescriptor, fields.get(fieldDescriptor));
       } else if (this.builder.hasField(fieldDescriptor)) {
-        dup.fields.put(
+        dup.setFieldInternal(
+            context,
             fieldDescriptor,
             wrapField(context, fieldDescriptor, this.builder.getField(fieldDescriptor)));
       }
diff --git a/ruby/tests/stress.proto b/ruby/tests/stress.proto
index 517e746..e7a0042 100644
--- a/ruby/tests/stress.proto
+++ b/ruby/tests/stress.proto
@@ -3,10 +3,10 @@
 package stress_test_protos;
 
 message TestMessage {
-  int32 a = 1;
+  optional int32 a = 1;
   repeated M b = 2;
 }
 
 message M {
-  string foo = 1;
+  optional string foo = 1;
 }
diff --git a/ruby/tests/stress.rb b/ruby/tests/stress.rb
index 4ad37c1..c564320 100755
--- a/ruby/tests/stress.rb
+++ b/ruby/tests/stress.rb
@@ -19,9 +19,11 @@
       data = TestMessage.encode(m)
       100_000.times do
         mnew = TestMessage.decode(data)
-        mnew = mnew.dup
+        mnew2 = mnew.dup
         assert_equal m.inspect, mnew.inspect
         assert_equal data, TestMessage.encode(mnew)
+        assert_equal m.inspect, mnew2.inspect
+        assert_equal data, TestMessage.encode(mnew2)
       end
     end
   end