As you all know, Project Kenai is not going to be around for long.
Therefore, JSR-275 will immediately relocate to its original host http://jsr-275.dev.java.net/ Until Kenai is shut down, this content remains for historic purposes. You may add something, but we may not be able to transfer anything. All but the SVN code repositories were deleted already. At a certain point, access to it will become Read-Only.
The JCP page of this project is http://www.jcp.org/en/jsr/detail?id=275 .
It contains the latest Public Review stage for download.
The Java SE Executive Committee (EC) has not approved the JSR-275 public review ballot. But it is not over... Now that we know better what the EC does not like, we can adjust accordingly. Reading the EC concerns (see below) there is a general feeling of too high complexity and many little annoyances we need to address. Here are few proposed changes to address their concerns:
- Rename Quantity to QuantityType and javax.measure.quantity.* to javax.measure.type.*
- Limit the number of predefined QuantityType sub-classes to the ones used by the SI units (still about 20).
- Remove the UNIT constant from the QuantityType subclasses. The mapping of the QuantityType class to its standard unit could be done through the SI instance (e.g. SI.getInstance().setTypeFor(METRE.divide(SECOND.pow(2)), Acceleration.class)).
- Make all Unit sub-classes package private.
- Make javax.measure.converter.* private (UnitConverter would be an interface in the javax.measure.unit.* package).
- Replace Measure with DecimalMeasure (non abstract) or simply remove Measure. Note: DecimalMeasure would be a combination of BigDecimal and a Unit (does it implements BigDecimal addition, multiplication? Are the names of these operations the same as BigDecimal (add, multiply) or the same as for units (plus, times)?)
- Change behavior of toString/Unit.valueOf(CharSequence) to use the locale format instead of the standard (less human readable) UCUM format.
With the changes above the new API would be about 30 public classes (one third of our original proposal):
- javax.measure Measurable, (DecimalMeasure ?) - javax.measure.unit Unit, UnitConverter, UnitFormat, Dimension, SystemOfUnits, SI, NonSI - javax.measure.type QuantityType, Mass, Length, Temperature, Angle, ...
Remarks: Not sure about the last package nor what "QuantityType" as opposed to the Quantity interface added value? In any case, type-safety and unit conversion should be archived the most convenient way possible in Java. While ICU4J may never make it into the JSR or a similar Java-wide approach (just for its own administrative hurdles ;-/) they accepted the term Measure and use it. Thus I wouldn't kill it light-hearted. The simple approach having Measure combine java.lang.Number and a Unit seems more flexible. BigDecimal is around quite long, but therefore extremely bulky and complicated to use (who cares about MathContext or RoundingMode unless they do complex math ?;-) Unless precison loss is inevitable by using Number I wouldn't force BigDecimal onto users who just wish to convert simple and small numbers. Let's not forget, that for Currency or Money sub-types this aimes at replacing it, even if there it may require internally using it for precision or historic (other API like JavaEE) reasons.
* Too big. The footprint for the user is too large.
The reference implementation (RI) Jar file is about 183K on this 183K about half are resources files for parsing/formatting (e.g to recognize "ft" as foot). This means that classes themselves are less than 100K. As noticed by some people already, this JSR and the "Date/Time/Money/Unit" complex is highly i18n' sensitive, thus more comparable to the Calendar or Currency types, Java has today. These usually contain additional resources often several MB in size.
* There are about 90 public types; which ones should a would-be user concentrate on?
They are only two main classes: Measurable (interface) and Measure (a combination of a value and a unit). Most classes are quantity sub-interfaces whose sole purpose is to tag the measurement type (or unit). Unfortunately, Java parameterization requires classes, not objects to be used. Hence to achieve compile type checking out of the box, we declare most of the quantities found in nature (temperature, mass, etc.)
* There are very few examples (or references to these) that show how the API might be used in practice. Some of the package comments and class comments have sample code, but the emphasis is mostly on extension rather than normal usage.
The main purpose of this JSR is to allow applications to tag their types (e.g. Sensor<Temperature>) and by doing so making the code more readable and less error-prone. We could call this JSR a "cosmetic" JSR (although unit parsing and formatting is all but cosmetic). There is very little behavior (except for unit conversion) and we have very few examples. But there is no problem adding more.
* The assignment of types to packages is unpredictable. I expect the most fundamental types to be in the top-level package, but Quantity, Unit, and Dimension are in nested packages.
We expect that most users manipulate measurements and not units directly. This is why we called our main package javax.measure (holding our main classes Measurable, Measure and MeasureFormat). Units, dimensions and quantities are lower level concept required to create measurements (hence sub-packages).
* The important types Measurable and Measure are named inconsistently. Something that is "measurable" can be measured, yet class Measure implements Measurable, implying that a measure can be measured. This doesn't make sense.
Measurable is indeed something which can be measured 'using any compatible unit' (e.g. my car velocity is measurable in km/h, miles/h, m/s). A Measure is the result of a measurement.for example, my car velocity is 123 km/h. Measure implements Measurable (it does not have to) means that my car velocity (123 km/h) can also be measured in others units such as miles/h or m/s. We do agree this is an important point which should be clarified in the spec. As consolidation with JSRs covering a matching scope like 310 is highly recommemded, there are further naming and probably even packaging questions ahead. 310 having introduced something named "Calendrical" yet a class instead of an interface provides plenty of housekeeping, not to mention merging overlapping pats.
* The interfaces UCUMParserConstant and UnitParserConstant exist only to define constants for the convenience of implementing classes UCUMParserTokenManager and UnitParserTokenManager, respectively. Interfaces should not be used in this way, see EJ2e, Item 19.
The package javax.measure.unit.format (and its classes) is not part of the spec (they are not part of the draft specification pdf). We should have removed them from the javadoc (our mistake). Note: The reference implementation uses javacc for parsing which generates these classes.
* The subinterfaces of the marker interface Quantity don't add any behavior. They serve two purposes: to define SI unit constants, which is (again) a bad practice; and to enable a limited form of compile-time checking: Measure<Mass> can't be assigned to Measure<Force>. Such checking is one of the stated design goals, but I think the user pays too high a price in comprehensibility to obtain it.
We happen to think on the contrary that the comprehensibility is accrued. Measure<Mass> and Measure<Force> is more readable than Measure, idem for Sensor<Temperature>, Vector<Velocity>, Complex<ElectricCurrent> etc.
* The design also doesn't fit well with existing practice in the standard libraries. For example, the timed methods in java.util.concurrent use a combination of long and java.util.concurrent.TimeUnit to express a duration. This was necessary for performance reasons, because the creation of an object just to hold the amount and the unit could easily end up taking longer than the duration it described. JSR-275 alludes briefly to the need to allow for this kind of use, but then proceeds to focus almost exclusively on bundling amount and unit together, without any mention of how to bridge the gap between TimeUnit and the proposed new API.
To bridge the gap, TimeUnit can be replaced by (or be a sub-class of) Unit<Duration> This is also where the otherwise almost redundant-looking Measurable interface comes into place. If using Measure which also needs to address ultra high precision required by e.g. Climate or Space Simulations, would slow down a real time process for which the ultra minimalistic TimeUnit in the concurrency API was designed for, then a Measurable can bridge that gap.
* Of the discussions back in 2005, but from the voting record it appears that the JSR was approved initially with many reservations expressed; there is an implication that the EC expected those reservations to be addressed during the review process.
Most reservations were due to the failure of the previous JSR and of a possible lack of interest for such JSR in the industry The broad use of this JSR before its finalization seems to indicate that not only the industry is interested by the JSR (mostly because of system integration issues), but there is also an interest in the scientific community as well.