Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

package org.apache.fory.graalvm;

import java.io.Serializable;
import org.apache.fory.Fory;
import org.apache.fory.util.Preconditions;

public class CompatibleExample {
static Fory fory;
Expand All @@ -38,17 +40,44 @@ private static Fory createFory() {
.build();
// register and generate serializer code.
fory.register(Foo.class);
fory.register(Outer.class);
fory.register(Outer.Inner.class);
fory.ensureSerializersCompiled();
return fory;
}

public static void main(String[] args) {
System.out.println("CompatibleExample started");
Example.test(fory);
testInnerClass(fory);
System.out.println("CompatibleExample succeed 1/2");
// Test new created Fory at runtime
fory = createFory();
Example.test(fory);
testInnerClass(fory);
System.out.println("CompatibleExample succeed");
}

private static void testInnerClass(Fory fory) {
Outer outer = new Outer();
outer.value = 7;
Outer.Inner inner = outer.new Inner();
inner.value = 5;
Outer.Inner copy = (Outer.Inner) fory.deserialize(fory.serialize(inner));
Preconditions.checkArgument(copy.value == 5);
Preconditions.checkArgument(copy.outer().value == 7);
Preconditions.checkArgument(copy.outer() != outer);
}

public static class Outer {
public int value;

public class Inner implements Serializable {
public int value;

Outer outer() {
return Outer.this;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,10 @@ private static Class<?> loadClass(String className) {
/** Returns an Expression that create a new java object of type {@link CodecBuilder#beanClass}. */
protected Expression newBean() {
// TODO allow default access-level class.
// A non-static inner class has no no-arg constructor and `NewInstance` would need an outer
// instance, so allocate it without a constructor like JDK25+ does.
if (sourcePublicAccessible(beanClass)
&& (Modifier.isStatic(beanClass.getModifiers()) || !beanClass.isMemberClass())
&& (JdkVersion.MAJOR_VERSION < 25
|| ReflectionUtils.hasPublicNoArgConstructor(beanClass))) {
return new Expression.NewInstance(beanType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.fory.Fory;
Expand Down Expand Up @@ -369,4 +371,54 @@ public void testWriteCompatibleMap(boolean referenceTracking, boolean enableCode
((MapFields) (fory.deserialize(fory2.serialize(mapFields)))).toCanEqual(),
mapFields.toCanEqual());
}

public static class InnerClassHolder {
public int value;
public Inner inner;

public class Inner {
public int value;

InnerClassHolder outer() {
return InnerClassHolder.this;
}
}
}

@Test
public void testNonStaticInnerClass() {
Fory fory = foryBuilder().withRefTracking(true).withCodegen(true).build();
InnerClassHolder holder = new InnerClassHolder();
holder.value = 1;
holder.inner = holder.new Inner();
holder.inner.value = 2;
InnerClassHolder copy = serDe(fory, holder);
Assert.assertEquals(copy.value, 1);
Assert.assertEquals(copy.inner.value, 2);
Assert.assertSame(copy.inner.outer(), copy);

InnerClassHolder.Inner innerRootCopy = serDe(fory, holder.inner);
Assert.assertEquals(innerRootCopy.value, 2);
Assert.assertEquals(innerRootCopy.outer().value, 1);
Assert.assertSame(innerRootCopy.outer().inner, innerRootCopy);

Fory noRefFory = foryBuilder().withRefTracking(false).withCodegen(true).build();
InnerClassHolder outer = new InnerClassHolder();
outer.value = 3;
InnerClassHolder.Inner inner = outer.new Inner();
inner.value = 5;
InnerClassHolder.Inner innerCopy = serDe(noRefFory, inner);
Assert.assertEquals(innerCopy.value, 5);
Assert.assertEquals(innerCopy.outer().value, 3);
Assert.assertNotSame(innerCopy.outer(), outer);
Assert.assertNull(innerCopy.outer().inner);

// PriorityBlockingQueue holds an AbstractQueuedSynchronizer.ConditionObject inner instance.
PriorityBlockingQueue<Integer> queue =
new PriorityBlockingQueue<>(4, Collections.reverseOrder());
queue.addAll(Arrays.asList(1, 3, 2));
PriorityBlockingQueue<Integer> queueCopy = serDe(fory, queue);
Assert.assertEquals(queueCopy.poll(), Integer.valueOf(3));
Assert.assertEquals(queueCopy.size(), 2);
}
}
Loading