RPost wrote: >>Jeremy Boynes wrote: >> >>Having one JAR for the database is nice, but not if the price is >>post-compilation bytecode hacks. > > > So how does everyone feelf about pre-compilation sourcecode hacks? > > Would someone please state the need a little more clearly? Exactly what > class/classes need to be abstract for one purpose and concrete for another > and why? > > It seems that the issue is: > > IF targetJVM=1.3 then classX needs to be concrete > ELSEIF targetJVM=1.4 then classX needs to be abstract
That's not quite correct. Really it would be In JDK 1.3 classX needs to be concrete But in JDK 1.4 classX would be seen as abstract when *compiled* This is only a build issue, not a run-time issue, not a packaging issue. Let's take real code. Derby needs implementations of java.sql.* classes for JSR169, JDBC 2.1 and JDBC 3.0. JSR169 and JDBC 2.1 are (different) subsets of JDBC 3.0. The simple case is where a single implementation class can satisfy all of these JDBC requirements. Examples are EmbedStatement and EmbedDatabaseMetaData. In these cases the additional methods in JDBC 3.0 only use classes (or primitives) that exist in JSR169 and JDBC 2.1 environments. E.g. when running in JDBC 2.1, EmbedStatement has more methods (the JDBC 3.0 ones) than it needs to, but they are not accessible to applications since they are accessing the class through the JDBC 2.1 java.sql.Statement interface. The case that causes the problem is where a method in JDBC 3.0 references a class that does not exist in JSR169 and/or JDBC 2.1 environments. This could either be a class added by JDBC 3.0, added by JDK 1.4 or not available in the JSR 169 J2ME environment. Examples of these methods are: PreparedStatement.getParameterMetaData - returns ParameterMetaData interface, which is added in JDBC 3.0 ResultSet.getBigDecimal - returns BigDecimal which does not exist in the JSR169 environment. So Derby implements PreparedStatement (and the others are similar) by having: EmbedPreparedStatement - JSR169 EmbedPreparedStatement20 extends EmbedPreparedStatement - JDBC 2.1 EmbedPreparedStatement30 extends EmbedPreparedStatement20 - JDBC 3.0 All of these need to be concrete so that instances can be created in their required environments (J2ME/CDC/Foundation, JDK 1.3 and JDK 1.4). [note as checked in (in svn) EmbedPreparedStatement is abstract as that's what I'm trying to solve with this build discussion] These classes correctly implement the contract for java.sql.PreparedStatement in their own environment, but would cause *compile* issues in the other environments, e.g. compiling EmbedPreparedStatement20 in JDK 1.4 will fail as the compiler will indicate it does not implement all the required methods for PreparedStatement interfaces, "it should be abstract". compiling EmbedPreparedStatement30 in a J2ME or JDK 1.3 environment will fail as it depends on classes that do not exist in that environment. Soooooo, I can think of two solutions, maybe there are others, but this is what I can think of :-) A) Compile each file using the correct jars files for its environment, and control the build order to be: 1) EmbedPreparedStatement with J2ME/CDC/Foundation & JSR169 jars 2) EmbedPreparedStatement20 with JDK 1.3 jars 3) EmbedPreparedStatement30 with JDK 1.4 jars This is what is done today, though the first step is with the JDK 1.3 jars as the J2ME is a work in progress. B) Compile in a single environment JDK 1.4 and to avoid the compiliation failures make the classes abstract in the code and modify the byte code after compilation. I'm willing to go with A) or B) and I prefer A) with the main issue being ii) below. The reason I proposed B as an alternative, was for two reasons: i) to simplify life for new developers of Derby, rather than requiring them to download basically three JDK setups, just require a single one. And continuing with this approach will mean four environments shortly, as Derby takes advantage of JDK 1.5 features. ii) I don't see a way for developers to easily download the required J2ME environment, there don't seem to be reference SDK's for this setup yet. Thus I can't check in final J2ME changes, which will delay adoption of Derby in the J2ME market. So, to repeat, this is a build environment issue for Derby, not a packaging or multiple code line issue. If the community wants Derby to support J2ME that Derby developers have to have an easy way to produce code that works in J2ME. That's the core issue, and it's the same even if have a single codeline, or a special codeline for J2ME, and it's the same issue if we have a single jar for Derby or a jar per environment. For the full details of how Derby will implement JDBC classes, see the design doc in this Jira bug. http://issues.apache.org/jira/browse/DERBY-97 Dan.
