diff --git a/src/main/java/org/cojen/tupl/remote/DerivedTable.java b/src/main/java/org/cojen/tupl/remote/DerivedTable.java index 2dd19d249..d9a53150b 100644 --- a/src/main/java/org/cojen/tupl/remote/DerivedTable.java +++ b/src/main/java/org/cojen/tupl/remote/DerivedTable.java @@ -159,7 +159,7 @@ public void dispose() throws RemoteException { } Class rowType() { - return RowTypeCache.find(mDescriptor); + return RowTypeCache.findRow(mDescriptor); } public static final class Serializer implements org.cojen.dirmi.Serializer { diff --git a/src/main/java/org/cojen/tupl/remote/RowTypeCache.java b/src/main/java/org/cojen/tupl/remote/RowTypeCache.java index 69dfb59b9..18bc5dc26 100644 --- a/src/main/java/org/cojen/tupl/remote/RowTypeCache.java +++ b/src/main/java/org/cojen/tupl/remote/RowTypeCache.java @@ -23,9 +23,9 @@ import org.cojen.tupl.core.TupleKey; +import org.cojen.tupl.table.MultiCache; import org.cojen.tupl.table.RowGen; import org.cojen.tupl.table.RowStore; -import org.cojen.tupl.table.SoftCache; import org.cojen.tupl.table.Unpersisted; /** @@ -33,27 +33,38 @@ * * @author Brian S. O'Neill */ -final class RowTypeCache extends SoftCache, byte[]> { +final class RowTypeCache extends MultiCache, byte[], RuntimeException> { private static final RowTypeCache THE = new RowTypeCache(); /** * @param descriptor see RowStore#primaryRowInfo */ - static Class find(byte[] descriptor) { - return THE.obtain(TupleKey.make.with(descriptor), descriptor); + static Class findPlain(byte[] descriptor) { + return THE.cacheObtain(TYPE_1, TupleKey.make.with(descriptor), descriptor); + } + + /** + * @param descriptor see RowStore#primaryRowInfo + */ + @SuppressWarnings("unchecked") + static Class findRow(byte[] descriptor) { + return (Class) THE.cacheObtain(TYPE_2, TupleKey.make.with(descriptor), descriptor); } private RowTypeCache() { } @Override - @SuppressWarnings("unchecked") - protected Class newValue(TupleKey key, byte[] descriptor) { + protected Class cacheNewValue(Type type, TupleKey key, byte[] descriptor) { ClassMaker cm = RowGen.beginClassMakerForRowType (DerivedTable.class.getPackageName(), DerivedTable.class.getSimpleName()); - cm.implement(Row.class).addAnnotation(Unpersisted.class, true); + cm.addAnnotation(Unpersisted.class, true); + + if (type == TYPE_2) { + cm.implement(Row.class); + } - return (Class) RowStore.primaryRowInfo(cm.name(), descriptor).makeRowType(cm); + return RowStore.primaryRowInfo(cm.name(), descriptor).makeRowType(cm); } } diff --git a/src/main/java/org/cojen/tupl/remote/ServerTable.java b/src/main/java/org/cojen/tupl/remote/ServerTable.java index 7b73c3391..60c5414fd 100644 --- a/src/main/java/org/cojen/tupl/remote/ServerTable.java +++ b/src/main/java/org/cojen/tupl/remote/ServerTable.java @@ -173,26 +173,26 @@ public boolean isEmpty() throws IOException { public RemoteTable derive(String typeName, byte[] descriptor, String query, Object... args) throws IOException { - RowInfo info = RowStore.primaryRowInfo(typeName, descriptor); - Class rowType; + // Always generate a row type interface rather than trying to find the type by name. + // There's no reason to assume that the server will have an interface that the client + // has, and it might not match anyhow. + Class rowType = RowTypeCache.findPlain(descriptor); + return new ServerTable((BaseTable) mTable.derive(rowType, query, args)); + /* Attempt to find the interface by name. findRowType: { try { rowType = Session.current().resolveClass(typeName); RowInfo existing = RowInfo.find(rowType); + RowInfo info = RowStore.primaryRowInfo(typeName, descriptor); if (existing.allColumns.equals(info.allColumns)) { - info = existing; break findRowType; } } catch (ClassNotFoundException | IllegalArgumentException e) { // Row type class doesn't exist or it's not a RowInfo. } - - // FIXME: Use RowTypeCache. No need to preserve the type name. - throw new IllegalArgumentException("FIXME: Unknown type: " + typeName); } - - return new ServerTable((BaseTable) mTable.derive(rowType, query, args)); + */ } @Override