Changes.txt (DC, 06.21.02) -=---------=- TINI SDK 1.10 -=---------=- -------------------------------------------------------------------- Go to http://www.ibutton.com/TINI/book.html for an online version of "The TINI Specification and Developer's Guide". -------------------------------------------------------------------- See API_Changes.txt for changes to the com.dalsemi API. See 1-Wire_Changes.txt for changes to the com.dalsemi.onewire (formerly com.ibutton) API. See Limitations.txt for a partial list of current limitations. See Versions.txt for version information on software that is included in this distribution. Significant Fixes & Changes -=========================- 1.10 -==- -=============- Problem : Sometimes must set the date 1 hour off from the intended time Since : 1.1 Beta 2 Description: During daylight savings time, entering a time of 13:00:00 would result in a clock set to 12:00:00. Solution : New DateCommand code fixes the problem. -=============- Problem : Calling disconnect() on an HTTPURLConnection can sometimes cause a NullPointerException. Since : Beta (before tini_1.0) Description: If an error occurred in initialization, or disconnect was called before the URLConnection was completely set up, there would be some uninitialized objects, which disconnect would try to use. Solution : Check for null in the disconnect() method. -=============- Problem : Calling Vector.setSize() makes the vector unusable. Since : Beta (before tini_1.0) Description: When calling setSize to make the vector smaller (usually calling setSize(0)) the other elements in the vector should be set to 'null', but instead we accidentally were setting the whole object array to null (forgot to type the array index '[i]'). Solution : Make sure to index into the array. -=============- Problem : TINI's FTP server doesn't work well with CuteFTP's 'UP directory' button. Since : Beta (before tini_1.0) Description: CuteFTP uses the optional 'CDUP' command, which is the equivalent of issuing a 'CD ..' command. Solution : Implement the 'CDUP' command in the FTP server. -=============- Problem : Javakit would still let certain files overwrite bank 0. Since : Beta (before tini_1.0) Description: A code path was exposed that would allow certain files to freely overwrite bank 0 without even asking first. This is very rude behavior. Solution : Add more bank 0 protection in JavaKit. -=============- Problem : Slush's DateCommand would incorrectly account for time zone offsets. Since : 1.1 Beta 1 Description: If you typed in '123000 +6' (i.e. 12:30 at time zone offset +6 hours) your time would come out as 6:30. Solution : Problem fixed. -=============- Problem : Constant strings would sometimes get swept away by the GC. Since : Beta (before tini_1.0) Description: When creating a new string from a constant pool string during periods of heavy memory use (a la TINIHttpServer) it was possible for the new string to be collected before it was returned. Solution : Don't invoke GC on String creates. -=============- Problem : Multi-dimension array dimensions sometimes incorrect. Since : Beta (before tini_1.0) Description: A 'obj = new int[3][2][1]' would think that the object at obj[0] was an 'int[][]', but obj[1] was an 'int[]', and obj[2] was an 'int'. Solution : Fixed the dimension issue. -=============- Problem : November 30, 2001 DST behavior incorrect. Since : Beta (before tini_1.0) Description: Certain last days of the month would exhibit incorrect DST behavior due to bad results from Clock.getDayOfWeek(). Solution : Fix the method Clock.getDayOfWeek(). -=============- Problem : Long 'to' strings for the mailto protocol would get chopped off. Since : Beta (before tini_1.0) Description: The write method in the mailto protocol would skip bytes if the buffer was full due to an indexing problem. Solution : Fix the indexing problem in 'MailToPrintStream'. -=============- Problem : A Thread stopped with Thread.stop() could lock the TINI up. Since : Beta (before tini_1.0) Description: A Thread stopped by Thread.stop() doesn't get a chance to release its locks. Solution : Implement a function to release all the locks held by a particular thread. -=============- Problem : Calling read() on a closed InputStreamReader caused a NullPointerException. Since : Beta (before tini_1.0) Description: The underlying input stream was set to null to denote the stream as closed. Solution : Check the underlying stream for null and throw an IOException if it is null. -=============- Problem : Object.wait(long, int) did not check for illegal nano values. Since : Beta (before tini_1.0) Description: The nanosecond argument to Object.wait() must be between 0 and 1000000. Solution : Check for incorrect nanosecond values. -=============- Problem : Hashtable.put() returned incorrect values when replacing an object in the hashtable. Since : Beta (before tini_1.0) Description: put() would return an instance of the private inner class HashtableEntry, rather than the actual Object that HashtableEntry encapsulated. Solution : Return the correct object. -=============- Problem : Vector.indexOf() and lastIndexOf() throw NullPointerExceptions. Since : Beta (before tini_1.0) Description: When a null object is inserted into the list, these methods would not handle their searches correctly. Solution : Handle case when a null might exist in the Vector's list. -=============- Problem : When starting processes in the background, you could get NullPointerExceptions when reading from standard input. Since : Beta (before tini_1.0) Description: When starting in the background, SystemInputStream's root stream was set to null. Solution : If the root stream is set to null, change it to a NullInputStream. -=============- Problem : Telnet through Windows XP echoes everything twice. Since : Beta (before tini_1.0) Description: Although all other Telnet Clients assume that the server will echo, Windows XP assumes that it needs to do the echoing. This is a problem on TINI because TINI does no option negotiation automatically, unlike other servers. Solution : Change TINI to immediately request that TINI does the echoing. -=============- Problem : Static initializer checks makes the Virtual Machine slow. Since : 1.1 Beta 1 Description: We were performing a complete check for static initialization in all instances required by the Java VM specification. Solution : There are some optimizations. For instance, if all the initializers in the API have run, we can set a global bit to tell us to no longer check for application classes. -=============- Problem : 1.1 is much slower than 1.0. Since : 1.1 Beta 1 Description: New functionality had slowed down the virtual machine. Solution : Implemented optimized byte codes of common instruction sequences for speed improvements. Also worked the entire byte code interpreter over for efficiency improvements. -=============- Problem : There is some interesting DHCP information we are not printing. Since : Beta (before tini_1.0) Description: N/A Solution : Print the lease time of the DHCP client if active. -=============- Problem : Slush's DateCommand would sometimes show an incorrect day of the week for the GMT time, but the correct one for the localized time. Since : Beta (before tini_1.0) Description: Incomplete use of the com.dalsemi.system.Clock class could result in an incorrect day-of-the-week stored, which Slush did not check for. Solution : Removed the printing of GMT time (it was more trouble than it was worth). You can still get the GMT time by using a new '-g' tag to the Date command. -=============- Problem : Some changes for code sharing in array processing caused incorrect exceptions to be thrown by System.arraycopy(). Since : 1.1 Beta 2 Description: We made some changes to share code the did simple bounds and reference checking. It checked first for negative array size, then for length, then for null references. However, System.arraycopy should check for null first. Solution : Added checks for null in the arraycopy implementation. -=============- Problem : Sending a serial break does not always work on serial0 and serial1. Since : Beta (before tini_1.0) Description: N/A Solution : Breaks are fixed -=============- Problem : Reading the real time clock turns off interrupts for an unacceptable period of time. Since : Alpha (before tini_1.0) Description: N/A Solution : Time with interrupts turned off was reduced to 86 microseconds. -=============- Problem : Calling close() on a CAN Bus object may throw an exception. Since : Alpha (before tini_1.0) Description: N/A Solution : Fixed. -=============- Problem : CanBus Media ID Mask Enable does not work. Since : Alpha (before tini_1.0) Description: All the CanBus methods dealing with Media IDs did not work correctly. Solution : Fixed. -=============- Problem : Using TINIExternalAdapter changes the external interrupt trigger to "level trigger" Since : Alpha (before tini_1.0) Description: The problem did not allow the use of the DS2480 based 1-Wire and edge triggered external interrupts. Solution : Fixed. -=============- Problem : In com.dalsemi.comm.CanBus setTSEG1() and setTSEG2() does not allow the setting of tqu to 1. Since : Alpha (before tini_1.0) Description: 1tqu was thought to not be a legal CAN value, so it was restricted. Solution : Restriction removed -=============- Problem : The com.dalsemi.tininet.http.HTTPServer class can generate incomplete responses to GET requests. Since : Beta (before tini_1.0) Description: The server did not synchronize calls to in.available with in.read while reading HTML pages. This could cause the page length to be inconsistant with the page content if the page changed between these method calls. Solution : in.available is now included in synchronized block. -=============- Problem : com.dalsemi.tininet.http.HTTPServer.serviceRequests can leak sockets if a failure occurs spawning a new Thread. Since : Beta (before tini_1.0) Description: serviceRequests expects the new Thread to clean up the socket when it is finished using it. If the Thread is not created the socket is never closed. Solution : Added a catch Throwable block to clean up the socket when any exception is thrown in serviceRequests. -=============- Problem : No version control for native libraries (.tlib). Since : Beta (before tini_1.0) Description: Running code in a tlib file built for a different firmware revision can cause random code execution and could ultimately cause damage to memory structures and files. Solution : Added support in TINIOS/a390 for checking/inserting hardware and firmware revision information. System.loadLibrary will now throw an UnsatisfiedLinkError if it finds the version information that does not match the current version. Legacy tlib files will still load but cannot be checked against the hardware or firmware revisions. See Native_Methods.txt for more information. -=============- Problem : No support in native library source for NESTED conditional blocks. Since : Beta (before tini_1.0) Description: N/A Solution : Added support in macro(.exe) for nested conditional blocks. -=============- Problem : No support in native library source for $include statements within conditional blocks. Since : Beta (before tini_1.0) Description: Macro, the native library macro and equate preprocessor, was recently updated to support conditional blocks but only assembler code was allowed in these blocks. Example: DEBUG_ON EQU 1 ;... IF (DEBUG_ON != 0) ; spew some debug using info_* and debug_* functions ENDIF Equates and macros were always processed regardless of whether they were in conditional blocks or not. Solution : Macro now supports $include statements within conditional blocks. Example: DS_400 EQU 0 ; IF (DS_400 != 0) $include(ds400.inc) ENDIF IF (DS_400 == 0) $include(ds390.inc) ENDIF This will allow the use of different macro and equate definitions based on a conditional statement. -=============- Problem : Java divide operations are slow. Since : Alpha (before tini_1.0) Description: Divides were performed using a shift-and-subtract algorithm. Solution : Division operations now make use of the microcontroller's arithmetic coprocessor. Speedups are on the order of up to 15x (speedup will vary depending on the number of leading zeros in the operands). -=============- 1.10 Beta 2 -=========- -=============- Problem : java.lang.Thread interrupt behavior did not match behavior of Sun's JDK 1.1 implementation. Specifically, Sun's implementation registered interrupt() calls even when a Thread was not sleeping or waiting. Calls to interrupted() and isInterrupted() returned true in this case. Also, when/if a Thread actually did call sleep, wait, etc., sometime after a call to interrupt, an InterruptedException would be thrown. Previous versions of TINIOS registered interrupts only if interrupt was called on a Thread that was sleeping, waiting, etc. at that moment in time. Since : 1.0 Beta Description: Behavior of interrupt is poorly documented in javadocs and JLS. Solution : TINI's interrupt behavior was changed to match Sun's JDK 1.1 behavior. -=============- Problem : Threads sometimes do not wake up from Thread.sleep even when there are no higher priority Threads to be scheduled. Since : 1.10 Beta 1 Description: N/A Solution : Fixed. -=============- Problem : Thread.setPriority has no effect after a Thread has been started. Since : 1.10 Beta 1 Description: After a Thread has been started a call to setPriority does not change a Thread's behavior. Solution : Fixed. -=============- Problem : Slush's 'date' command did not work as advertised. Since : 1.02 Description: Slush's 'date' command should be able to handle setting the time zone to a String like "+10", meaning it is set to GMT + 1000. However, this case was throwing an exception. Solution : Added logic to detect setting a time zone to a number of hours offset from GMT correctly. -=============- Problem : String.indexOf and lastIndexOf returning incorrect values in special cases. Since : Alpha (before tini_1.0) Description: Special cases, such as searching for the empty string starting from a specified location, returned wrong values. For instance... "abc".indexOf("", -99999); was returning '-99999' instead of '0'. Solution : Fixed the special cases. -=============- Problem : Class casting in the virtual machine and java.lang.Class was broken. Since : Alpha (before tini_1.0) Description: Class casting was broken with respect to array dimensions, since we were not checking them. Casting a String[] to a String was an allowed operation. Solution : Begin checking array dimensions when casting. -=============- Problem : URL creation with contexts did not return correct values. Since : 1.0 Beta Description: Creating a URL in the context of another URL was causing problems, mostly with anchors. If the original (context) URL defined an anchor, and the new URL just defined a file, we were keeping the old context around. Solution : Get rid of the file and anchor on creating new URLs in context. -=============- Problem : Class.getSuperclass() was not returning null if the java.lang.Class object represented an interface class. Since : 1.0 Beta Description: Interfaces don't really have superclasses, even though you can clearly state in the source file that 'interface A extends B', although really in the java class file, A 'implements' B, sort of. Solution : Check for interface class and return null from getSuperclass(). -=============- Problem : We were always truncating milliseconds in the GregorianCalendar class. Since : 1.0 Beta Description: When calculating the 'long' time value, we were just totally leaving out the milliseconds. Solution : Incorporate the milliseconds. This required several changes to the GregorianCalendar constructors and to Date.parse(String), which were inadvertently relying on bad behavior from the GregorianCalendar calculate methods. -=============- Problem : Overriding ThreadGroup.uncaughtException() did not work. Since : 1.0 Beta Description: In the VM, we were specifically jumping into the code for ThreadGroup.uncaughtException(), which is basically an empty method. Solution : Rather than point to the code for the ThreadGroup class, get the ThreadGroup object from the VM and point to its class, which makes up point to the correct code. Then added some logic to detect if a thread has entered the uncaughtException method, so that if uncaughtException() throws an uncaught exception, we are not stuck forever in an infinite loop. -=============- Problem : Exceptions in static initializers did very bad things. Since : 1.1 Beta 1 Description: Code executed when a static initializer threw an exception had not been tested and scrogged the system. Solution : Catch exceptions when running static initializers and return the proper exception as defined by the JVMS -=============- Problem : Class.getInterfaces() was returning an empty array on arrays. Since : 1.1 Beta 1 Description: Arrays should return Cloneable and Serializable as interfaces. Solution : Special check for arrays on getInterfaces() call added. -=============- Problem : On a java.lang.Class representing an interface, getMethods() was returning all of java.lang.Object's methods, but none of its superinterface's methods. Since : 1.1 Beta 1 Description: getMethods() for an interface class should return superinterface methods. Solution : Changed method to check for interface class, and loop through all superinterfaces looking for methods. -=============- Problem : NoSuchMethodException and InvocationTargetException declared incorrectly. Since : 1.1 Beta 1 Description: NoSuchMethodException had no public constructors, and InvocationTargetException had incorrect constructor signatures. Solution : Fixed to match JDK declaration. -=============- Problem : SimpleTimeZone was not serialization compatible with JDK 1.2 as claimed. Since : 1.1 Beta 1 Description: startMode and endMode were not supposed to be set to anything by default, only when the multiple argument SimpleTimeZone constructor was called Solution : Fixed to mimic JDK operation. -=============- Problem : Some ObjectInputValidations were not being registered by ObjectInputStream. Since : 1.1 Beta 1 Description: Inserted an ObjectInputValidation with the highest priority would execute a segment of code that never put the ObjectInputValidation in our table. Solution : Fix the case when the priority of the validation object is highest. -=============- Problem : ObjectInputValidation doesn't run at all. Since : 1.1 Beta 1 Description: There was a casting problem removing ObjectInputValidation objects from our internal Vector. Solution : Fixed the casting problem. -=============- Problem : Reflection information for primitive arrays was not being stored properly. Since : 1.1 Beta 1 Description: There was an array indexing problem when processing a primitive array. Solution : Correct the indexing problem. -=============- Problem : Class.forName() would occasionally return useless garbage. Since : 1.1 Beta 1 Description: Class objects created in native were being tagged with a random process number, so when that 'random' process would eventually run, those Class objects would be swept. Solution : Use the correct process number for GC tagging. -=============- Problem : Tools.getClassNameFromNum(int) would return bad data or scrog when the class number was invalid. Since : 1.1 Beta 1 Description: We weren't checking for invalid class numbers. Solution : Check to see if the class number is in the valid range (for API and Application) or that the class actually exists (for dynamic classes) before trying to make a String of the class name. -=============- Problem : When JavaKit starts spewing, its nearly impossible to get hits on the RESET button to work. Since : The birth of JavaKit Description: JavaKit spent all its time in a loop reading and printing. Solution : Added a small sleep after each serial port read. This makes response under spewing conditions a little bit better. -=============- Problem : Stack sizes were not configurable. Since : Alpha (before tini_1.0) Description: The Java stack for every thread was a set size. Solution : Wrote TINIOS methods that allow stack configuration. You can resize the Java stack of the currently running thread. See the documentation for com.dalsemi.system.TINIOS.setStackSize(int) for more information. -=============- Problem : Dynamically loaded classes could not be unloaded and have their resource freed without ending the application. Since : 1.1 Beta 1 Description: Unloading was not designed into the Beta 1 release. Solution : Store the ClassLoader for every dynamically loaded class, and add a method that allows you to unload all classes loaded by that ClassLoader. See the documentation for com.dalsemi.system.classloader.TINIClassLoader.unloadClasses() for more information. -=============- Problem : BufferedReader would skip a byte every so often. Since : 1.02 Description: When a line would end at the same point the buffer does, we would accidentally skip a byte in the next buffer read. Solution : Don't skip that byte. -=============- Problem : You can forName an array of primitives of type 'void'. Since : 1.1 Beta 1 Description: Void is stored as a primitive type just like long, int, and char, but we weren't checking to make sure that we weren't trying to create an array of type "[V". Solution : Check the primitive type before creating a java.lang.Class object representing "[V". -=============- Problem : InetAddress.getAddress() was returning a length 16 byte array even for IPv4 addresses. The important 4 bytes were stored at the END. Since : 1.1 Beta 1 Description: All IP addresses are now represented internally as 16 bytes. We weren't returning it as a 4 byte address when it was a valid IPv4 address. Solution : Make Inet4Address.getAddress() just return the last 4 bytes. -=============-