Home » Language IDEs » Objectteams » Is serialization of roles/teams supported?
| | |
Re: Is serialization of roles/teams supported? [message #518596 is a reply to message #515966] |
Thu, 04 March 2010 15:15 |
Abdullah O. Messages: 4 Registered: March 2010 |
Junior Member |
|
|
Hi all,,
Serialization in OT/J should be attached, as a concept, to inner classes. According to Java language definition, serializing inner classes "is strongly discouraged " , and a set of reasons have been mentioned; the most important one is that: implementing the names and synthetic fields of inner classes is a compiler dependent issue. This may come out with different serial-IDs, for example.
Because OT/J realizes the roles by the means of inner-classes, then its a must to serialize the outer team class in order to allow roles to be serialized (since role classes are non-static) as well.
Also, we should make sure that roles (and teams) don't implement any transient fields! to make sure of a complete serialization process.
Finally, there is nothing prevents OT/J to support serialization (as a default choice), but the above.
Regards
Abdullah
|
|
|
Re: Is serialization of roles/teams supported? [message #518630 is a reply to message #518596] |
Thu, 04 March 2010 16:31 |
Stephan Herrmann Messages: 1853 Registered: July 2009 |
Senior Member |
|
|
Abdullah O. wrote on Thu, 04 March 2010 10:15 | Hi all,,
Serialization in OT/J should be attached, as a concept, to inner classes. According to Java language definition, serializing inner classes "is strongly discouraged " ,
|
That's interesting. Do you have a reference for this?
Quote: | and a set of reasons have been mentioned; the most important one is that: implementing the names and synthetic fields of inner classes is a compiler dependent issue. This may come out with different serial-IDs, for example.
|
That shouldn't disturb us, because there's only one OT/J compiler (currently).
Which reminds me, that support for a third party OT/J compiler would require
diligent specification of several aspects of the byte code we produce.
Quote: |
Because OT/J realizes the roles by the means of inner-classes, then its a must to serialize the outer team class in order to allow roles to be serialized (since role classes are non-static) as well.
|
That's true. Let's see, we have several implicit references that should be
considered, some of which must be included in serialization to preserve
the semantics, others are optional:
- role -> team: MUST be included
- role -> base: MUST be included
- team -> role: OPTIONAL
- team -> base: no direct dependence (only via role)
- base -> team: no direct dependence
- base -> role: OPTIONAL (implicit, invisible reverse of role->base).
Do you agree on this table?
Quote: |
Also, we should make sure that roles (and teams) don't implement any transient fields! to make sure of a complete serialization process.
|
Well, isn't it the purpose of transient fields to actually provide for incomplete
serialization (i.e., after deserialization those fields are simply set to defaults)?
Quote: |
Finally, there is nothing prevents OT/J to support serialization (as a default choice), but the above.
|
thanks,
Stephan
|
|
|
Re: Is serialization of roles/teams supported? [message #518660 is a reply to message #515966] |
Thu, 04 March 2010 17:23 |
Olaf Otto Messages: 22 Registered: July 2009 |
Junior Member |
|
|
Very triky one.
The thing with serialization is that it is essentially persistence, and should thus be explicit to avoid unwanted serialization. Can we gurantee the consistency of the object teams application's runtime state, for instance in the context of role migration and team activation / deactivation? How do we deal with Thread-related state?
Basically, we might need to take care of all generated fields and must make them either transient or clearly define their effect on serialization.
In OT-JPA, for instance, I declared all generated fields of a base as transient to the persistence context, since it is unclear whether a user intends to serialize these. This is also important to prevent the (not unlikely) case of an explosion of serializations due to the potentially large transitive hull of a team.
Probably, marking references to the DoublyWeakHashMap transient and adding a role state restauration to a Roles readObject method might be more suitable? This way, role instances would only be serialized iff 1) The role or team is serialized and, in the latter case, the team contained a non-transitive user-defined field referencing the corresponding role instance(s). (See OTClassDescriptor in ObjectTeamsSemanticsAdapter for my approach to this problem for the JPA).
Looking at this, I think we might have to consider a reasonable amount of constraints. This will be a little more triky.
Best,
Olaf
|
|
|
Re: Is serialization of roles/teams supported? [message #518704 is a reply to message #518660] |
Thu, 04 March 2010 19:25 |
Stephan Herrmann Messages: 1853 Registered: July 2009 |
Senior Member |
|
|
Olaf Otto wrote on Thu, 04 March 2010 12:23 | Very triky one.
The thing with serialization is that it is essentially persistence, and should thus be explicit to avoid unwanted serialization. Can we gurantee the consistency of the object teams application's runtime state, for instance in the context of role migration and team activation / deactivation? How do we deal with Thread-related state?
|
Thanks for mentioning threads. Yes, all state relating to per-thread activation
should be skipped for serialization. For role migration I see no problems.
In any given state, there's no way to see that migration has happened.
Am I missing anything?
Quote: |
Basically, we might need to take care of all generated fields and must make them either transient or clearly define their effect on serialization.
In OT-JPA, for instance, I declared all generated fields of a base as transient to the persistence context, since it is unclear whether a user intends to serialize these. This is also important to prevent the (not unlikely) case of an explosion of serializations due to the potentially large transitive hull of a team.
|
I was thinking of a few annotations whereby transientness of synthetic
fields would be configured. Would that be useful also for OT/JPA?
If so we should come up with annotation names that are suitable for
both use cases.
Quote: |
Probably, marking references to the DoublyWeakHashMap transient and adding a role state restauration to a Roles readObject method might be more suitable? This way, role instances would only be serialized iff 1) The role or team is serialized and, in the latter case, the team contained a non-transitive user-defined field referencing the corresponding role instance(s). (See OTClassDescriptor in ObjectTeamsSemanticsAdapter for my approach to this problem for the JPA).
|
That sounds like a good way if the user decides against automatic reading
of all contained roles.
Quote: |
Looking at this, I think we might have to consider a reasonable amount of constraints. This will be a little more triky.
Best,
Olaf
|
In order to simplify addressing this issue I've filed two bugs
https://bugs.eclipse.org/304728 - serializing object dependencies
https://bugs.eclipse.org/304729 - serializing global activation state.
Feel free to comment either on the bugs or here.
Stephan
|
|
|
Re: Is serialization of roles/teams supported? [message #518875 is a reply to message #518704] |
Fri, 05 March 2010 10:51 |
Olaf Otto Messages: 22 Registered: July 2009 |
Junior Member |
|
|
Stephan Herrmann wrote on Thu, 04 March 2010 14:25 |
Thanks for mentioning threads. Yes, all state relating to per-thread activation
should be skipped for serialization. For role migration I see no problems.
In any given state, there's no way to see that migration has happened.
Am I missing anything?
|
I guess not - I was just wondering whether deserializing a role that was migrated after serialization could create an inconsistency with regard to references from the original team and the team targeted by migration.
Quote: |
I was thinking of a few annotations whereby transientness of synthetic
fields would be configured. Would that be useful also for OT/JPA?
If so we should come up with annotation names that are suitable for
both use cases.
|
I am quite scepting about this one. It basically means that the user has to understand infrastructure aspects of the OT appliation, which is not simple, as there may be quite a few generated fields and transient references involved.
Even with annotations, the user could not (in a simple fashion) control the instances that will be serialized (due to the limited control of the contents of the generated fields). Thus the behavior would still differ significantly from the standard java serialization. I'd rather we kept this as simple as possible.
In summary, I think we should stick to the explicit form of serialization, i.e. to only serialize the contents of non-transient user-defined fields, with the exception of the base and team reference of a role which, as Stephan mentioned before, must be serialized in order to restore the OT applications state upon deserialization.
Concerning relationship to JPA: Serialization would lead to a better spec coverage there. According to the JPA spec, a persistent class can persist non @Entities if they are serializable.
|
|
| | |
Re: Is serialization of roles/teams supported? [message #519949 is a reply to message #518875] |
Wed, 10 March 2010 15:31 |
Stephan Herrmann Messages: 1853 Registered: July 2009 |
Senior Member |
|
|
Olaf Otto wrote on Fri, 05 March 2010 05:51 |
Quote: |
I was thinking of a few annotations whereby transientness of synthetic
fields would be configured. Would that be useful also for OT/JPA?
If so we should come up with annotation names that are suitable for
both use cases.
|
I am quite scepting about this one. It basically means that the user has to understand infrastructure aspects of the OT appliation, which is not simple, as there may be quite a few generated fields and transient references involved.
|
I would never let the user refer to synthetic fields, I was thinking of more
abstract annotations that would internally be mapped to affecting specific
synthetic fields.
Quote: |
Even with annotations, the user could not (in a simple fashion) control the instances that will be serialized (due to the limited control of the contents of the generated fields). Thus the behavior would still differ significantly from the standard java serialization. I'd rather we kept this as simple as possible.
In summary, I think we should stick to the explicit form of serialization, i.e. to only serialize the contents of non-transient user-defined fields, with the exception of the base and team reference of a role which, as Stephan mentioned before, must be serialized in order to restore the OT applications state upon deserialization.
|
That's good reasoning. I created a prototype for a second strategy
where automatic serialization is kept to the minimum:
- neither org.objectteams.Team nor ..DoublyWeakHashMap are declared as Serializable.
- essential synthetic fields are marked as transient with the exception of the two mandatory links of a role: to its team and to its base.
- o.o.Team provides additional methods to be called by client code:
- writeGlobalActivationState / readGlobalActivationState -- for persisting/restoring a global (ALL_THREADS) team activation
- restore() -- for initializing (empty) role caches (mandatory)
- restoreRole(Class,Object) -- for restoring the linkage of one role
With this strategy, serializable teams should/must also implement specific
writeObject / readObject methods, optionally calling some of the new
predefined methods. For a simple example (no nesting / layering...) this
works fine in several variants of what is serialized and what is not.
Here is the test program I used:
public class B implements java.io.Serializable {
int i;
public B(int i) { this.i = i; }
public String toString() {
return "B("+this.i+")";
}
void foo() {
System.out.println("foo:"+this);
}
}
import java.io.*;
public team class TeamA implements Serializable {
protected class R implements Serializable playedBy B {
// persistent role field:
String v;
// ctor for explicit role creation:
protected R(String v, int i) { base(i); this.v = v; }
// ctor for roles created by lifting:
public R(B b) {
this.v = "R created by lifting "+super.toString();
}
// identify ourselves:
public String toString() {
String suffix = "";
if (TeamA.this.theOKR == this) // identity check!
suffix = " [OK]";
return "Role R("+this.v+") with base "+baseString()+suffix;
}
String baseString() -> String toString();
// test callin incl. team activation and lifting:
void bar () {
System.out.println("invoked bar on "+this);
TeamA.this.printRoles("\t");
}
bar <- after foo;
}
// persistent team field:
protected R theOKR;
public TeamA() {
this.theOKR = new R("OK", 42);
new R("better", 23);
System.out.println("created:"+this);
printRoles("");
}
public String toString() {
return super.toString() + " with OK Role: "+this.theOKR;
}
public void printRoles(String indent) {
System.out.println(indent+"all roles:");
for (Object o : getAllRoles())
System.out.println(indent+"\t"+o);
}
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
{
System.out.println("write:"+this+"; globally active:"+this.isActive(ALL_THREADS));
out.defaultWriteObject();
// custom serialization:
writeGlobalActivationState(out);
R[] roles = getAllRoles(R.class);
out.writeInt(roles.length);
for(R r : roles)
out.writeObject(r);
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
// custom deserialization:
readGlobalActivationState(in); // currently includes a call to restore()
int n = in.readInt();
for (int i=0; i<n; i++)
restoreRole(R.class, in.readObject());
System.out.println("read:"+this+" globally active:"+this.isActive(ALL_THREADS));
}
}
import java.io.*;
public class Main {
static FileInputStream instream;
static Object[] roles;
public static void main(String[] args) throws IOException, ClassNotFoundException {
if (args[0].equals("out")) {
line("create TeamA");
TeamA t = new TeamA();
roles = t.getAllRoles(); // prevent gc
t.activate(org.objectteams.Team.ALL_THREADS);
//t.activate();
line("create B(1)");
B b = new B(1);
line("call foo()");
b.foo();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(args[1]));
line("write B");
out.writeObject(b);
line("write t");
out.writeObject(t);
out.close();
} else {
instream = new FileInputStream(args[1]);
ObjectInputStream in = new ObjectInputStream(instream);
line("read B");
B b = (B)in.readObject();
System.out.println("Retrieved B: "+b);
line("call foo()");
b.foo();
line("read TeamA");
TeamA t = (TeamA)in.readObject();
System.out.println("Retrieved TeamA: "+t);
line("call foo()");
b.foo();
line("");
}
}
static void line(String msg) {
System.out.println("----------------"+msg+": ----------------");
}
}
Writing to file:
$ot Main out fff
----------------create TeamA: ----------------
Team.<init>()
created:TeamA@9ced8e with OK Role: Role R(OK) with base B(42) [OK]
all roles:
Role R(better) with base B(23)
Role R(OK) with base B(42) [OK]
----------------create B(1): ----------------
----------------call foo(): ----------------
foo:B(1)
invoked bar on Role R(R created by lifting TeamA$__OT__R@1358f03) with base B(1)
all roles:
Role R(better) with base B(23)
Role R(R created by lifting TeamA$__OT__R@1358f03) with base B(1)
Role R(OK) with base B(42) [OK]
----------------write B: ----------------
----------------write t: ----------------
write:TeamA@9ced8e with OK Role: Role R(OK) with base B(42) [OK]; globally active:true
Reading from file
$ ot Main in fff
----------------read B: ----------------
Retrieved B: B(1)
----------------call foo(): ----------------
foo:B(1)
----------------read TeamA: ----------------
Team.<init>()
read:TeamA@497934 with OK Role: Role R(OK) with base B(42) [OK] globally active:true
Retrieved TeamA: TeamA@497934 with OK Role: Role R(OK) with base B(42) [OK]
----------------call foo(): ----------------
foo:B(1)
invoked bar on Role R(R created by lifting TeamA$__OT__R@1358f03) with base B(1)
all roles:
Role R(OK) with base B(42) [OK]
Role R(R created by lifting TeamA$__OT__R@1358f03) with base B(1)
Role R(better) with base B(23)
----------------: ----------------
Would this bring us closer to a solution?
If anyone wishes to experiment with my prototype please let me know and
I will package/upload the required batch compiler and otre.jar.
cheers,
Stephan
|
|
| | | |
Re: Is serialization of roles/teams supported? [message #569568 is a reply to message #518660] |
Thu, 04 March 2010 19:25 |
Stephan Herrmann Messages: 1853 Registered: July 2009 |
Senior Member |
|
|
Olaf Otto wrote on Thu, 04 March 2010 12:23
> Very triky one.
>
> The thing with serialization is that it is essentially persistence, and should thus be explicit to avoid unwanted serialization. Can we gurantee the consistency of the object teams application's runtime state, for instance in the context of role migration and team activation / deactivation? How do we deal with Thread-related state?
Thanks for mentioning threads. Yes, all state relating to per-thread activation
should be skipped for serialization. For role migration I see no problems.
In any given state, there's no way to see that migration has happened.
Am I missing anything?
Quote:
> Basically, we might need to take care of all generated fields and must make them either transient or clearly define their effect on serialization.
> In OT-JPA, for instance, I declared all generated fields of a base as transient to the persistence context, since it is unclear whether a user intends to serialize these. This is also important to prevent the (not unlikely) case of an explosion of serializations due to the potentially large transitive hull of a team.
I was thinking of a few annotations whereby transientness of synthetic
fields would be configured. Would that be useful also for OT/JPA?
If so we should come up with annotation names that are suitable for
both use cases.
Quote:
> Probably, marking references to the DoublyWeakHashMap transient and adding a role state restauration to a Roles readObject method might be more suitable? This way, role instances would only be serialized iff 1) The role or team is serialized and, in the latter case, the team contained a non-transitive user-defined field referencing the corresponding role instance(s). (See OTClassDescriptor in ObjectTeamsSemanticsAdapter for my approach to this problem for the JPA).
That sounds like a good way if the user decides against automatic reading
of all contained roles.
Quote:
> Looking at this, I think we might have to consider a reasonable amount of constraints. This will be a little more triky.
>
> Best,
> Olaf
In order to simplify addressing this issue I've filed two bugs
https://bugs.eclipse.org/304728 - serializing object dependencies
https://bugs.eclipse.org/304729 - serializing global activation state.
Feel free to comment either on the bugs or here.
Stephan
|
|
|
Re: Is serialization of roles/teams supported? [message #569588 is a reply to message #518704] |
Fri, 05 March 2010 10:51 |
Olaf Otto Messages: 22 Registered: July 2009 |
Junior Member |
|
|
Stephan Herrmann wrote on Thu, 04 March 2010 14:25
> Thanks for mentioning threads. Yes, all state relating to per-thread activation
> should be skipped for serialization. For role migration I see no problems.
> In any given state, there's no way to see that migration has happened.
> Am I missing anything?
I guess not - I was just wondering whether deserializing a role that was migrated after serialization could create an inconsistency with regard to references from the original team and the team targeted by migration.
Quote:
> I was thinking of a few annotations whereby transientness of synthetic
> fields would be configured. Would that be useful also for OT/JPA?
> If so we should come up with annotation names that are suitable for
> both use cases.
I am quite scepting about this one. It basically means that the user has to understand infrastructure aspects of the OT appliation, which is not simple, as there may be quite a few generated fields and transient references involved.
Even with annotations, the user could not (in a simple fashion) control the instances that will be serialized (due to the limited control of the contents of the generated fields). Thus the behavior would still differ significantly from the standard java serialization. I'd rather we kept this as simple as possible.
In summary, I think we should stick to the explicit form of serialization, i.e. to only serialize the contents of non-transient user-defined fields, with the exception of the base and team reference of a role which, as Stephan mentioned before, must be serialized in order to restore the OT applications state upon deserialization.
Concerning relationship to JPA: Serialization would lead to a better spec coverage there. According to the JPA spec, a persistent class can persist non @Entities if they are serializable.
|
|
|
Re: Is serialization of roles/teams supported? [message #569649 is a reply to message #569588] |
Wed, 10 March 2010 15:31 |
Stephan Herrmann Messages: 1853 Registered: July 2009 |
Senior Member |
|
|
Olaf Otto wrote on Fri, 05 March 2010 05:51
> Quote:
> > I was thinking of a few annotations whereby transientness of synthetic
> > fields would be configured. Would that be useful also for OT/JPA?
> > If so we should come up with annotation names that are suitable for
> > both use cases.
>
>
> I am quite scepting about this one. It basically means that the user has to understand infrastructure aspects of the OT appliation, which is not simple, as there may be quite a few generated fields and transient references involved.
I would never let the user refer to synthetic fields, I was thinking of more
abstract annotations that would internally be mapped to affecting specific
synthetic fields.
Quote:
> Even with annotations, the user could not (in a simple fashion) control the instances that will be serialized (due to the limited control of the contents of the generated fields). Thus the behavior would still differ significantly from the standard java serialization. I'd rather we kept this as simple as possible.
>
> In summary, I think we should stick to the explicit form of serialization, i.e. to only serialize the contents of non-transient user-defined fields, with the exception of the base and team reference of a role which, as Stephan mentioned before, must be serialized in order to restore the OT applications state upon deserialization.
That's good reasoning. I created a prototype for a second strategy
where automatic serialization is kept to the minimum:
neither org.objectteams.Team nor ..DoublyWeakHashMap are declared as Serializable.
essential synthetic fields are marked as transient with the exception of the two mandatory links of a role: to its team and to its base.
o.o.Team provides additional methods to be called by client code:
writeGlobalActivationState / readGlobalActivationState -- for persisting/restoring a global (ALL_THREADS) team activation
restore() -- for initializing (empty) role caches (mandatory)
restoreRole(Class,Object) -- for restoring the linkage of one role
With this strategy, serializable teams should/must also implement specific
writeObject / readObject methods, optionally calling some of the new
predefined methods. For a simple example (no nesting / layering...) this
works fine in several variants of what is serialized and what is not.
Here is the test program I used:
public class B implements java.io.Serializable {
int i;
public B(int i) { this.i = i; }
public String toString() {
return "B("+this.i+")";
}
void foo() {
System.out.println("foo:"+this);
}
}
import java.io.*;
public team class TeamA implements Serializable {
protected class R implements Serializable playedBy B {
// persistent role field:
String v;
// ctor for explicit role creation:
protected R(String v, int i) { base(i); this.v = v; }
// ctor for roles created by lifting:
public R(B b) {
this.v = "R created by lifting "+super.toString();
}
// identify ourselves:
public String toString() {
String suffix = "";
if (TeamA.this.theOKR == this) // identity check!
suffix = " [OK]";
return "Role R("+this.v+") with base "+baseString()+suffix;
}
String baseString() -> String toString();
// test callin incl. team activation and lifting:
void bar () {
System.out.println("invoked bar on "+this);
TeamA.this.printRoles("\t");
}
bar <- after foo;
}
// persistent team field:
protected R theOKR;
public TeamA() {
this.theOKR = new R("OK", 42);
new R("better", 23);
System.out.println("created:"+this);
printRoles("");
}
public String toString() {
return super.toString() + " with OK Role: "+this.theOKR;
}
public void printRoles(String indent) {
System.out.println(indent+"all roles:");
for (Object o : getAllRoles())
System.out.println(indent+"\t"+o);
}
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
{
System.out.println("write:"+this+"; globally active:"+this.isActive(ALL_THREADS));
out.defaultWriteObject();
// custom serialization:
writeGlobalActivationState(out);
R[] roles = getAllRoles(R.class);
out.writeInt(roles.length);
for(R r : roles)
out.writeObject(r);
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
// custom deserialization:
readGlobalActivationState(in); // currently includes a call to restore()
int n = in.readInt();
for (int i=0; i<n; i++)
restoreRole(R.class, in.readObject());
System.out.println("read:"+this+" globally active:"+this.isActive(ALL_THREADS));
}
}
import java.io.*;
public class Main {
static FileInputStream instream;
static Object[] roles;
public static void main(String[] args) throws IOException, ClassNotFoundException {
if (args[0].equals("out")) {
line("create TeamA");
TeamA t = new TeamA();
roles = t.getAllRoles(); // prevent gc
t.activate(org.objectteams.Team.ALL_THREADS);
//t.activate();
line("create B(1)");
B b = new B(1);
line("call foo()");
b.foo();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(args[1]));
line("write B");
out.writeObject(b);
line("write t");
out.writeObject(t);
out.close();
} else {
instream = new FileInputStream(args[1]);
ObjectInputStream in = new ObjectInputStream(instream);
line("read B");
B b = (B)in.readObject();
System.out.println("Retrieved B: "+b);
line("call foo()");
b.foo();
line("read TeamA");
TeamA t = (TeamA)in.readObject();
System.out.println("Retrieved TeamA: "+t);
line("call foo()");
b.foo();
line("");
}
}
static void line(String msg) {
System.out.println("----------------"+msg+": ----------------");
}
}
Writing to file:
$ot Main out fff
----------------create TeamA: ----------------
Team.<init>()
created:TeamA@9ced8e with OK Role: Role R(OK) with base B(42) [OK]
all roles:
Role R(better) with base B(23)
Role R(OK) with base B(42) [OK]
----------------create B(1): ----------------
----------------call foo(): ----------------
foo:B(1)
invoked bar on Role R(R created by lifting TeamA$__OT__R@1358f03) with base B(1)
all roles:
Role R(better) with base B(23)
Role R(R created by lifting TeamA$__OT__R@1358f03) with base B(1)
Role R(OK) with base B(42) [OK]
----------------write B: ----------------
----------------write t: ----------------
write:TeamA@9ced8e with OK Role: Role R(OK) with base B(42) [OK]; globally active:true
Reading from file
$ ot Main in fff
----------------read B: ----------------
Retrieved B: B(1)
----------------call foo(): ----------------
foo:B(1)
----------------read TeamA: ----------------
Team.<init>()
read:TeamA@497934 with OK Role: Role R(OK) with base B(42) [OK] globally active:true
Retrieved TeamA: TeamA@497934 with OK Role: Role R(OK) with base B(42) [OK]
----------------call foo(): ----------------
foo:B(1)
invoked bar on Role R(R created by lifting TeamA$__OT__R@1358f03) with base B(1)
all roles:
Role R(OK) with base B(42) [OK]
Role R(R created by lifting TeamA$__OT__R@1358f03) with base B(1)
Role R(better) with base B(23)
----------------: ----------------
Would this bring us closer to a solution?
If anyone wishes to experiment with my prototype please let me know and
I will package/upload the required batch compiler and otre.jar.
cheers,
Stephan
|
|
| | |
Goto Forum:
Current Time: Mon Sep 23 14:19:19 GMT 2024
Powered by FUDForum. Page generated in 0.07405 seconds
|