Java 2 SDK for Solaris Developer's Guide

Incompatibilities in Java 2 SDK for Solaris

The following is intended to be a complete list of all cases in which a program that works under JDK 1.0 or 1.1 of the Java platform would fail to work under Java 2 SDK for Solaris. Most of these incompatibilities involve unusual circumstances and are not expected to affect most existing programs.

Language Incompatibilities

Compilers in JDK 1.0 and 1.1 compiled some types of illegal code without producing warnings or error messages. The Java 2 SDK for Solaris compiler is more stringent in ensuring that code conforms to the JLS. The following list summarizes the types of illegal code that compiled with JDK 1.0 or 1.1 compilers but do not compile with Java 2 SDK for Solaris.

  1. Previous compilers passed some initializations of int types to long types. These are flagged as errors in Java 2 SDK for Solaris. In the following program,


    public class foo {
    	int i = 3000000000;
    	int j = 6000000000;
    }

    both the initialization to i and j are in error. Previous compilers would only report the incorrect initialization of i. The initialization of j would have overflowed silently [bug 4035346].

  2. Previous compilers allowed the implicit assignment conversion from char to byte and short for character literals that fit into 8 bits. The compiler does not allow such implicit assignment conversion in Java 2 SDK for Solaris. For example,


    byte b = 'b';

    will not pass the compiler. Use an explicit cast for such conversions [bug 4030496].


    byte b = (byte)'b';
  3. The Java 2 SDK for Solaris compiler will not pass 0xL (not a legal hex literal). Previous compilers parsed it as zero [bug 4049982].

  4. The Java 2 SDK for Solaris compiler will not pass ''' (and therefore '\u0027') (not a legal char literal) . Use '\'' instead [bug 1265387].

  5. The Java 2 SDK for Solaris compiler will not pass "\u000D" (not legal in string and char literals). The CR and LF characters (\u000A and \u000D) terminate lines, even in comments [bug 4086919]. The following code is not :


    //This comment about \u000D is not legal; it is really two lines.

    Use \r instead [bug 4063147].

  6. The Java 2 SDK for Solaris compiler will not pass the type void[] (not legal) [bug 4034979].

  7. Do not combine the abstract method modifier with private, final, native, or synchronized modifiers; it is not legal [bug 1266571].

  8. Previous compilers would pass double-assignment of final variables in some circumstances. For example, the following two samples would pass JDK 1.1-based compilers (even though both involve double-assignment of a final variable). The Java 2 SDK for Solaris compiler will not pass such assignments [bugs 4066275 and 4056774].


    public class Example1 {
    		public static void main(String[] argv) {
    			int k=0;
    			for (final int a;;) {
    				k++;
    				a=k;
    				System.out.println("a="+a);
    				if (k>3)
    					return;
    			}
    		}
    }
    
    public class Example2 {
    		final int k;
    		Example2() {
    			k = 1;
    		}
    		Example2(Object whatever) {
    			this();
    			k = 2;
    		}
    }
    static public void main(String[] args) {
    		Example2 t = new Example2(null);
    		System.out.println("k is "+ t.k);
    }
  9. You cannot reference a non-static field with an apparently static field expression of the form Classname.fieldname. Prior to Java 2 SDK for Solaris, javac silently tolerated such expressions as if they had been written this.fieldname [bug 4087127].

  10. Section 5.5 of the JLS specifies that a cast between two interface types is a compile-time error if the interfaces contain methods with the same signature but different return types. The compiler did not generate this compile-time error prior to Java 2 SDK for Solaris [bug 4028359)]. For example, the following program now generates a compile-time error:


    interface Noisy {
    		int method();
    }
    interface Quiet {
    		void method();
    }
    public class InterfaceCast {
    		public static void main(String[] args) {
    			Noisy one = null;
    			Quiet two = (Quiet) one;
    		}
    }
  11. Java 2 SDK for Solaris does not accept an assignment expression as the third subexpression of a conditional statement. For example, the Java 2 SDK for Solaris compiler throws an error in the following statement.


    myVal = condition ? x = 7 : x = 3;

    If this problem occurs in existing code, place the offending assignment expression in parentheses to compile it as in previous versions of the JDK:


    myVal = condition ? x = 7 : (x = 3);
  12. In previous releases of javac, the compiler incorrectly omitted the initialization if a field was initialized to its default value [bug 1227855)]. This behavior can lead to different semantics for programs like the following:


    abstract class Parent {
    		Parent() {
    			setI(100);
    		}
    }
    	abstract public void setI(int value);
    }
    public class InitTest extends Parent {
    		public int i = 0;
    		public void setI(int value) {
    			i = value;
    		}
    }
    	public static void main(String[] args) {
    		InitTest test = new InitTest();
    		System.out.println(test.i);
    }

    This program produces incorrect output (100) when compiled with earlier versions of javac. The Java 2 SDK for Solaris javac produces the correct output (0).

    Single class examples can be formulated as well:


    public class InitTest2 {
    		public int j = method();
    		public int i = 0;
    		public int method() {
    			i = 100;
    			return 200;
    		}
    }
    public static void main(String[] args) {
    		InitTest2 test = new InitTest2();
    		System.out.println(test.i);
    }

    Before, the output was 100. Now it is 0. The same phenomenon can occur in programs using reference types and null.

  13. Concerning accessibility in qualified names, JLS 6.6.1 states the following:

    A member (field or method) of a reference (class, interface, or array) type or a constructor of a class type is accessible only if the type is accessible and the member or constructor is declared to permit access."

    Prior to Java 2 SDK for Solaris, the compiler did not enforce this rule correctly. It granted access if the member or constructor was declared to permit access without regard to the accessibility of the type to which it belonged as in the following illegal program.


    import pack1.P1;
    public class CMain {
    		public static void main(String[] args) {
    			P1 p1 = new P1();
    // The accesses to field 'i' below are
    // illegal, as the type of 'p2', the
    // class type 'pack1.P2', is not accessible.
    			p1.p2.i = 3;
    			System.out.println(p1.p2.i);
    		}
    }
    package pack1;
    public class P1 {
    		public P2 p2 = new P2();
    }
    // Note the absence of an access modifier, making
    // 'P2' accessible only from within package 'pack1'.
    public class P2 {
    		public int i = 0;
    }

    With the introduction of inner classes in Java 2 SDK for Solaris, a member of a class or interface might be another class or interface, as well as a field or method. Java 2 SDK for Solaris enforces the accessibility rules described to inner classes as well.

  14. Prior to Java 2 SDK for Solaris, the compiler failed to detect that certain classes were abstract. This happened when a subclass declared a method with the same name as an abstract, package-private method defined in a superclass from a different package. No overriding occurs even though the methods have the same name. As an example, compiling these files:


    package one;
    public abstract class Parent {
    		abstract void method();
    }
    
    package two;
    public class Child extends one.Parent {
    	void method() {}
    }

    yields the error message:


    two/Child.java:3: class two.Child is not able to provide an
    implementation for the method void method() declared in class
    one.Parent because it is private to another package. class
    two.Child must be declared abstract.
    	public class Child extends one.Parent {
    			^
  15. The Java 2 SDK for Solaris compiler properly detects duplicate, nested labels. These are disallowed by the JLS (the following example statement is illegal).


    sameName:
    while (condition) {
    	sameName:
    	while (condition2) {
    		break sameName;
    	}
    }
  16. The Java 2 SDK for Solaris compiler properly detects a labeled declaration. These declarations are disallowed by the JLS. This is a fix for bug 4039843.

  17. The Java 2 SDK for Solaris compiler recognizes a new keyword, strictfp, so programs can no longer use strictfp as an identifier. The Java 2 SDK for Solaris compiler uses the new keyword to set a modifier bit in the method data structures. The platform specification previous to Java 2 SDK for Solaris required that this bit be zeroed. Code written using the new keyword executes in strict floating-point mode (the default defined for the Java platform). Code that does not use the new keyword executes in default floating-point mode. This enables implementations to make better use of some processors to deliver higher performance.

    Some numeric code not marked with the strictfp keyword might behave differently in Java 2 SDK for Solaris than in previous versions. Such code might also behave differently depending on the implementation of the Java platform. Overflow or underflow can occur in different circumstances and create slightly different results. These differences are not expected to have an impact on most numeric code. However, code that is vulnerable to floating-point behavior might be affected.

  18. JDK 1.1 extended the syntax of expressions to allow a class name to qualify a reference to a current instance using the keyword this (as in the following example).


    PrimaryNoNewArray: ...
                    ClassName . this

    The value of such an expression is a reference to the current instance of the enclosing class (ClassName), which must exist.

    Prior to Java 2 SDK for Solaris, the javac compiler treated such expressions incorrectly. It produced a reference to the current instance of the innermost enclosing class that was a subtype of the type named by ClassName. The compiler now implements such expressions properly.

  19. JDK 1.1, extended the syntax of expressions allowing a class name to qualify a reference to a current instance using the keyword this (as in the following example).


    PrimaryNoNewArray: ...
                    ClassName . this

    This syntax allows access to members using constructions such as:


    ClassName.this.fieldname
    ClassName.this.methodname( ... ) 

    The presence of inner classes made this extension necessary because more than one current instance might occur at a given point in the program. The inner classes specification neglected to include a similar extension for the super keyword (as in the following example).


    FieldAccess: ...
                    ClassName.super.Identifier
    MethodInvocation:...
                    ClassName.super.Identifier(ArgumentList_opt) 

    Java 2 SDK for Solaris implements these constructs in anticipation of their inclusion in the forthcoming second edition of the JLS.

    In each case, the current instance is the current instance of the enclosing class (ClassName), which must exist.

    The following example shows how the need for the qualified super notation might arise in practice.


    class C {
    		void f() { ... }
    }
    class D extends C {
    		void f() {
                // overrides f() to run it in a new thread
    			new Thread(new Runnable() {
    				public void run() {
    					D.super.f();
    				}
    			}).start();
    		}
    }

    Implementation Note: If you need to use an access method, it must reside in the class named by ClassName, not in its superclass. The superclass does not have to be defined in the same compilation unit, and can have been compiled previously.

  20. JDK 1.1 extended the syntax of expressions allowing a constructor invocation using the keyword super to be qualified with a reference to an outer instance (as in the following example).


    ExplicitConstructorInvocation: ...
    	Primary.super(ArgumentList_opt); 

    The corresponding case for constructor invocations using this was inadvertently omitted:


    ExplicitConstructorInvocation: ...
    	Primary.this(ArgumentList_opt); 

    Java 2 SDK for Solaris implements the construct in anticipation of its inclusion in the forthcoming second edition of the JLS.

  21. The Inner Classes specification does not permit an inner class to declare a member interface. This rule is enforced in Java 2 SDK for Solaris, but such declarations are silently tolerated in JDK 1.1-based releases. For example, the following program is incorrectly accepted by javac in JDK 1.1-based releases, but is rejected in Java 2 SDK for Solaris.


    class InnerInterface {
    		class Inner {
    			interface A { }
    		}
    }

    A static member class is not an inner class; it is a top-level class (as that term is defined by the Inner Classes specification). The javac in both JDK 1.1-based releases and Java 2 SDK for Solaris accepts the following program as correct.


    class NestedInterface {
    		static class Inner {
    			interface A { }
    		}
    }

    A local class is never a top-level class, so the following example is also illegal; both javac JDK 1.1-based releases and Java 2 SDK for Solaris report a syntax error.


    class LocalNestedInterface {
    	void foo()
    			 static class Inner {
    			 	interface A { }
    			}
    	}
    }
  22. The Java 2 SDK for Solaris compiler strongly enforces the restriction that a package cannot contain a type and a subpackage of the same name. This change makes it illegal to compile a class whose fully qualified name was the same as the fully qualified name of a package on the classpath. This change also makes it illegal to compile a class whose package (or some proper prefix) would have the same name as an existing class. This is a fix for bug 4101529. The following are some examples of classes that now fail to compile:


    \\Example 1
    package java.lang.String;
    class Illegal {
    }
    
    \\Example 2
    package java;
    class util {
    }

Runtime Incompatibilities

  1. In JDK 1.0 and 1.1, the runtime systems finalize objects (invoke their finalize methods) somewhat aggressively. Sometimes all eligible but unfinalized objects would be finalized at the end of nearly every garbage-collection cycle. Code written for such systems can unintentionally depend upon this prompt garbage collection-invoked finalization for correct operation, which can lead to complicated bugs and deadlocks.

    In Java 2 SDK for Solaris, finalization is not performed directly by the garbage collector. Instead, objects are finalized only by a high-priority thread. So, in a busy program, the time between the moment an object becomes eligible and the moment when it is finalized might be longer than in previous versions of the runtime system.

    In Java 2 SDK for Solaris, the runtime system properly implements the definition of finalization in the JLS, so this difference is not, strictly speaking, an incompatibility. This change might, however, cause programs to malfunction if they rely upon prompt finalization. Many such programs can be repaired by using reference objects instead of finalize methods. (Reference objects are implemented by the java.lang.ref.Reference class and its subclasses.) A less preferable workaround is to periodically invoke the System.runFinalization method at regular intervals.

  2. Virtual machines in releases prior to Java 2 SDK for Solaris accept some class files that should be rejected (according to the JLS). Typically, these class files have one or more of the following problems:

    1. Extra bytes are at the end of the class file.

    2. The class file contains method or field names that do not begin with a letter.

    3. The class attempts to access private members of another class.

    4. The class file has other format errors, including illegal constant pool indexes and illegal UTF-8 strings.

    Java 2 SDK for Solaris VM more closely implements the specification, so it can be stricter on all of these points.

    Until the RC2 release of Java 2 SDK for Solaris, this strict checking was the default behavior. However, final product testing revealed that many existing Java applications failed to run because of some of these checks. In particular, obfuscated code frequently suffers from problems a and b, while some inner-class code generated by previous compilers suffers from problem c. Java 2 SDK for Solaris relaxed some of these checks to make it as easy as possible for developers and end users to upgrade to Java 2 SDK for Solaris.

    The Java 2 SDK for Solaris -Xfuture option enables the strictest possible class file format checks, access checks, and verification policies. Developers should start using this option as soon as possible for all new development work. This ensures that new Java applets and applications are prepared for migration to strict behavior when it again becomes the default.

    The Java Plug-in always uses the strict class file checks (as if the -Xfuture flag is set). The appletviewer ignores the -Xfuture flag and uses the more relaxed set of default checks.

  3. In Java 2 SDK for Solaris, an unimplemented abstract method or interface method causes an AbstractMethodError to be raised at runtime when the method is invoked. In previous versions, the error occurred during link time.

  4. Prior to Java 2 SDK for Solaris, putting code on CLASSPATH could make it more privileged. For example, prior to Java 2 SDK for Solaris, VMs would sometimes not require that some trusted class files pass verification. Verification depended on the installed security manager. For example, if the following method was in a class on CLASSPATH, and was called by an applet, then it could read the user.name property:


    String getUser() {
    	return System.getProperty("user.name");
    }

    In Java 2 SDK for Solaris, this kind of code requires a call to do Privileged (as in the following example).


    String getUser(){
    		return(String)
    		java.security.AccessController.doPrivileged
    																	(new PrivilegedAction(){
    			public Object run() {
    				return System.getProperty("username");
    			}
    		})
    }
    • The security model in Java 2 SDK for Solaris changes the way in which resources are accessed. When a security manager is in force, resources must reside at a URL that has been granted appropriate security permissions by a policy file. The default policy file,java.policy, grants all security permissions to resources located in the lib/ext directory, where extensions are stored. The default policy file is located at /lib/security/java.policy.

      In addition, an invocation to access system resources, as for example by ClassLoader.getResource, must be enclosed within an AccessController.doPrivileged call. Attempts to access system resources without use of a doPrivileged statement will fail. This is true even if the resources that are granted security permissions by the policy file.

  5. Prior to JDK 1.1.6, the default ISO 8859-1 character encoding had the name "8859_1". With JDK 1.1.6, this name changed to "ISO8859_1". The old name works when passed as an argument to methods in the API, but does not work when used in font.properties files.

  6. Each of the following classes in package java.util.zip has a constructor that accepts an int parameter to specify the buffer size:

    • DeflaterOutputStream

    • InflaterInputStream

    • GZIPInputStream

    • GZIPOutputStream

    In Java 2 SDK for Solaris, an IllegalArgumentException is thrown if the input parameter for buffer size is less than or equal to 0. In the JDK 1.1 platform, these constructors do not throw IllegalArgumentException if the size parameter is less than or equal to 0.

  7. When the Java 2 SDK for Solaris VM attempts to load a class file that is not of the proper class file format, a java.lang.ClassFormatError is thrown. A java.lang.UnsupportedClassVersionError is thrown when the virtual machine attempts to load a class file which is not of a supported major or minor version. Earlier versions of the virtual machine threw java.lang.NoClassDefFoundError when either of the above class file problems was encountered.

  8. In Java 2 SDK for Solaris, application classes are loaded by an actual ClassLoader instance. This makes it possible for application classes to use installed extensions and also separates the application class path, which is specified by the user, from the bootstrap class path, which is fixed and normally should not be modified by the user. The -Xbootclasspath option can be used to override the bootstrap class path if necessary.

    However, this means that in Java 2 SDK for Solaris, application classes no longer have all permissions by default. Instead, they are granted permissions based on the system's configured security policy. This might cause some applications that write their own security code based on the original security model in JDK 1.0 and 1.1 to throw an exception and not start in Java 2 SDK for Solaris. To work around this problem, run these applications with the oldjava application launcher, which is documented on the reference page for the Java application launcher. See Chapter 4, Command-Line Differences Between the Java 2 SDK and JDK 1.1 for more information on using the oldjava utility.

    See the Extension Mechanism Specification at http://java.sun.com/products/jdk/1.2/docs/guide/extensions/spec.html for more information regarding the new extension mechanism and its effect on class loading. The document provides relevant information regarding the new class loader delegation model and class loader API changes.

    See the JDK security documentation at http://java.sun.com/products/jdk/1.2/docs/guide/security/index.html for information regarding the security model of Java 2 SDK for Solaris.

  9. In Java 2 SDK for Solaris, the constructors of some classes in package java.io check for null input parameters. Such checks were not performed in earlier versions of the platform.

    • The constructors PrintStream(OutputStream out) and PrintStream(OutputStream out, boolean autoFlush) throws a NullPointerException if parameter out is null.

    • Similar checks have also been added in Java 2 SDK for Solaris to constructors InputStreamReader(InputStream in) and InputStreamReader(InputStream in, String enc). These constructors throw NullPointerException if parameter in is null.

    • In Java 2 SDK for Solaris, the constructors Reader(Object lock) and Writer(Object lock) now throw NullPointerException if parameter lock is null.

  10. In JDK 1.1 software, Thread.stop is able to interrupt a thread blocked in Object.wait or Thread.sleep. However, in Java 2 SDK for Solaris software running on the Solaris 8 operating environment with native threads, Thread.stop cannot interrupt a blocked thread. Java 2 SDK for Solaris behaves the same as the JDK 1.1 release with respect to Thread.stop when running on other operating systems or on a Solaris 2.6 operating platform.

  11. Java 2 SDK for Solaris contains a revised class-loading mechanism. Under the new class loader, if any class file belonging to a package in a jar file is signed, all class files belonging to the same package must have been signed by the same signers. It is no longer possible to use a jar file in which some classes of a package are signed and others are unsigned or signed by a different signer. jar files can still contain packages that are unsigned. However, if any packages contain signed classes, all class files of that package must be signed by the same signer. Existing jar files that don't meet this criterion are not usable with Java 2 SDK for Solaris or Runtime Environment.

  12. Foreground and background colors of native components can be set explicitly using the setForeground() and setBackground() methods. If the colors are not set explicitly, default colors are used as follows:

    • In the Java 2 platform, default colors of native components are taken to be the colors defined by the underlying operating system.

    • Prior to Java 2 SDK for Solaris, default colors were pre-defined by the Java platform itself.

Code compiled with JDK 1.1 that relies on the default colors can exhibit different and sometimes undesirable component appearance when run on Java 2 SDK for Solaris. For example, if the JDK 1.1 code explicitly sets the foreground color to white for a component label but uses the default background color, the label is not visible when run on Java 2 SDK for Solaris if the underlying operating system's default background color is white.

API Incompatibilities

  1. The ActiveEvent class now resides in the package java.awt. It used to be in java.awt.peer.

  2. The Swing and Accessibility packages (formerly in the com.sun.java.* namespace) have moved to the javax.* namespace. These packages now have the following names:

    • javax.swing

    • javax.swing.border

    • javax.swing.colorchooser

    • javax.swing.event

    • javax.swing.filechooser

    • javax.swing.plaf

    • javax.swing.plaf.basic

    • javax.swing.plaf.metal

    • javax.swing.plaf.multi

    • javax.swing.table

    • javax.swing.text

    • javax.swing.text.html

    • javax.swing.tree

    • javax.swing.undo

    • javax.accessibility

      Applications that use the old com.sun.java.swing* names for these packages from Swing 1.0 do not work in the Java 2 SDK for Solaris platform. Update these applications to use the new java.swing package names. A PackageRenamer tool is available at http://java.sun.com/products/jfc/PackageRenamer for making this conversion.


      Note -

      The packages com.sun.java.swing.plaf.windows and com.sun.java.plaf.motif have not changed names.


      If necessary, you can force applications using the old package names to work on the Java 2 SDK for Solaris platform by placing the Swing 1.0 jar file first on the boot class path:


      java -Xbootclasspath:<path to 1.0 swingall.jar>:<path to Java 2 SDK
      rt.jar> ...

      Note -

      The Java 2 SDK for Solaris Swing package has been modified to deal with Java 2 SDK for Solaris security. Therefore if you use this technique to run the Swing 1.0 classes with Java 2 SDK for Solaris in an environment where a security manager is present (that is, applets in a browser), the program might not run correctly.


  3. The following fields of class java.awt.datatransfer have been made final in Java 2 SDK for Solaris: stringFlavor and plainTextFlavor:


    public static final DataFlavor stringFlavor
    public static final DataFlavor plainTextFlavor
  4. Java 2 SDK for Solaris includes the java.util.List interface. As a result, existing source code might possibly produce a namespace conflict between java.awt.List and java.util.List.

    In Java 2 SDK for Solaris, using the wildcard import statements together causes a compiler error for code that contains the unqualified name List, as in the following example:


    import java.awt.*;
    import java.util.*;

    To work around this problem, either add an import statement such as


    import java.awt.List;

    to resolve the conflict throughout the file, or fully qualify the class name by the desired package at each point of use.

  5. In Java 2 SDK for Solaris, the field CHAR_UNDEFINED in class java.awt.event.KeyEvent has the value 0x0ffff. In JDK 1.1-based releases, the field had a value of 0x0. This change was made because 0 is a valid Unicode character and therefore cannot be used to define CHAR_UNDEFINED.

  6. In Java 2 SDK for Solaris, the signature of the java.io.StringReader.ready method changed so an IOException can be thrown if the StringReader is closed. Now the StringReader class properly implements the general contract spelled out in the abstract class java.io.Reader, which it extends.

  7. In Java 2 SDK for Solaris, the specifications for Integer.decode() and Short.decode() are explicit about the correct representation of negative numbers. Negative numbers always begin with a minus sign (-). If the number is hexadecimal or octal, the base specifier (0x, #, or 0), must come after the minus sign.

    In Java 2 SDK for Solaris, the specifications did not clearly state whether a minus sign should come before or after a base specifier. The actual implementations expected the base specifier (if any) to come before the minus sign (if any).

    For example, in Java 2 SDK for Solaris, decoding -0x5 returns -5 and decoding 0x-5 throws a NumberFormatException. In JDK 1.1, the results were opposite: -0x5 threw a NumberFormatException and 0x-5 returned -5.

    The decoding rules used in JDK 1.1 were unconventional and undocumented. However, some programs might rely on this behavior.

  8. In Java 2 SDK for Solaris, classes java.util.Vector and java.util.Hashtable have been retrofitted to implement the relevant interfaces in the new Collections Framework (java.util.Map, respectively). As a consequence, the semantics of the equals and hashCode methods have changed to provide value equality, rather than reference equality, as per the general contracts set forth in List.equals and Map.equals.

    This raises several compatibility issues:

    • "Self-reference" (inserting a Vector or Hashtable into itself) can now cause stack overflows under certain circumstances:

      1. If a Hashtable is inserted into itself as a key, the Hashtable becomes corrupt, and subsequent operations can cause stack overflow. (It has never been permissible to mutate an object that is serving as a Hashtable key Inserting an object into a Hashtable now qualifies as mutation, since it affects equals comparison.)

      2. If a Hashtable contains itself as a value (otherwise known as an element), equals and hashCode are undefined by the contract. If the hashCode or equals methods are called on such a "self-referential" Hashtable, a stack overflow can result.

      3. If a Vector contains itself as an element, equals and hashCode are undefined by the contract, and can cause a stack overflow.

    • Because equals and hashCode now depend on the contents of the Vector or Hashtable, they are now synchronized against other operations on the collection. Prior to Java 2 SDK for Solaris, they were unsynchronized. The additional synchronization could cause liveness problems if a client depended on the fact that equals or hashCode were unsynchronized.

    • Clients with explicit dependence on the "reference equality" behavior of equals for Vector or Hashtable do not operate properly. For example, suppose a program kept a Hashtable whose keys were all of the Vectors (or Hashtables) in some system. It was previously the case that each Vector (or Hashtable) was a distinct key, regardless of its contents. It is now the case that any two Vectors (or Hashtables) with the same contents are considered equal. Further, it is no longer legal to modify a Vector or Hashtable that is currently serving as the key in a Hashtable.

    • Because equals and hashCode now examine the entire contents of the Vector or Hashtable, they might run more slowly than they used to for large collections.

  9. The new version of the File class is compatible with both its originally intended behavior and its current common uses. However, some minor differences in behavior might cause some programs to fail.

    • The new version of the File class also removes redundant separator characters, including those at the end of a pathname string. So the expression new File("foo//bar/").getPath() evaluates to the string foo/bar on a Unix system.

  10. In Java 2 SDK for Solaris, the checkAccess method of java.lang.Thread is final. In the JDK 1.1 platform, checkAccess was not final [bug 4151102] .

  11. In Java 2 SDK for Solaris, the getInterfaces method of class java.lang.Class returns an array containing Cloneable and Serializable class objects when invoked on a class representing an array. In JDK 1.1, getInterfaces returned an empty array when invoked thus.

  12. The Java 2 SDK for Solaris abstract classes java.text.BreakIterator, java.text.SimpleTextBoundary, and java.text.Collator (and Collator's subclass java.text.RuleBasedCollator) no longer implement the Serializable interface as they did in JDK 1.1 [bug 4152965] .

  13. The Java 2 SDK for Solaris abstract method drawString(AttributedCharacterIterator,int,int) has been added to the java.awt.Graphics class as part of the Input Method Framework for use by the PersonalJavaTM platform. Subclasses of Graphics in applications based on the JDK 1.1 platform are likely to be rare. However, any such subclasses needs to provide an implementation of this new abstract method for use in conjunction with the Java 2 SDK for Solaris platform [bug 4128205].

  14. The String hash function implemented in JDK 1.1 releases did not match the function specified in the first edition of the JLS. In fact, the specified function cannot be implemented, in that it addresses characters outside of the input string. Additionally, the implemented function did not perform well on certain classes of strings, including URLs.

    To bring the implementation into accord with the specification, and to fix the performance problems, the specification and implementation have been modified. The Java 2 SDK for Solaris String hash() function is specified as:


    s[0] * 31^(n-1) + s[1] * 31^(n-2) + ... + s[n-1]

    where s[i] is the ith character of string s.

    This change should have no effect on the majority of applications. If an application has persistent data that depend on actual String hash values, it could theoretically be affected. However, the serialized representation of a Hashtable does not depend on the actual hash values of the keys stored in the Hashtable. Thus, applications relying on serialization for storage of persistent data are unaffected [bug 4045622].

  15. Java 2 SDK for Solaris does not support the Native Method Interface (NMI).

    If you have either written non-JNI native methods with the NMI supported by JDK 1.0, or embedded the runtime by way of the JNI Invocation Interface, you must re-link your native libraries before they can be used with Java 2 SDK for Solaris. In the Solaris environment, you have to replace -ljava in your link command line with -ljvm. You also have to rewrite to the JNI.


    Note -

    This change does not affect JNI programmers implementing native methods.


    As of Java 2 SDK for Solaris, Sun supports JNI only. JNI is the standard way to make your native libraries inter-operate with the Java programming language. In addition, JNI offers VM independence for any native code that you write. If your methods use NMI, please refer to Chapter 3, Java Native Interface (JNI) for information about migrating your native methods to JNI.

  16. Using Thread.suspend() can lead to a deadlock condition. This method is inherently unsafe and has been deprecated (along with other asynchronous thread methods, such as Thread.stop() and Thread.resume() [bug Id 4203325].

    Thread.suspend() is unsafe since it might cause a thread to be suspended, for instance, while it is in the midst of a synchronized method. This action can potentially lock out other threads, and might cause deadlock (please see http://java.sun.com/products//jdk/1.2/docs/guide/misc/threadPrimitiveDeprecation.html reference platform documentation for more detail).

  17. In JDK 1.1, Thread.stop can interrupt a thread blocked in Object.wait or Thread.sleep. In Java 2 SDK for Solaris running on the Solaris 2.6 environment with native threads, Thread.stop cannot interrupt a blocked thread. Java 2 SDK for Solaris behaves the same as JDK 1.1 with respect to Thread.stop when running on other operating systems or on the Solaris 2.6 environment.

  18. This section describes compatibility issues affecting developers who implement the interfaces in the java.sql package (primarily those implementing JDBC drivers). The following interfaces contain new methods in Java 2 SDK for Solaris:

    • java.sql.Connection

    • java.sql.DatabaseMetaData

    • java.sql.ResultSetMetaData

    • java.sql.ResultSet

    • java.sql.CallableStatement

    • java.sql.PreparedStatement

    • java.sql.Statement

      Source code that implements the JDK 1.1 versions of these interfaces do not compile properly under Java 2 SDK for Solaris unless you change it to implement the new methods.

      The following interfaces support new types in Java 2 SDK for Solaris:

    • java.sql.ResultSet

    • java.sql.CallableStatement

    • java.sql.PreparedStatement

      Source code that implements these interfaces and compiles correctly in Java 2 SDK for Solaris do not compile under the JDK 1.1 as the new types added to java.sql are not present.

  19. A public field, serialVersionUID, was introduced into the java.io.Serializable interface in Java 2 SDK for Solaris. This field should never have been introduced into the interface. Its meaning is unspecified, and its presence contradicts the java.io.Serializable specification.

    The API specification for java.io.Serializable states

    The serialization interface has no methods or fields."

    Furthermore, according to the serialization specification, the only way to get the serial version UID of a class is through the ObjectStreamClass.lookup(className).getSerialVersionUID() method. It does not make sense to try to get the serial version UID through a field that might or might not exist.

    The serial version UID is sometimes computed and sometimes explicitly defined in a class, but it is never inherited from a superclass or interface. Since interfaces cannot be instantiated directly, a serialVersionUID field in an interface can be of no use to the serialization system. In fact, the serialization system makes no use of this field.

    For these reasons, the public serialVersionUID field was removed in Java 2 SDK for Solaris. It is expected that this change will not break any existing applications.

Tool Incompatibilities

  1. In Java 2 SDK for Solaris, the javac -O option has a different meaning, and might have different performance effects on generated code than it does in JDK 1.1. javac -O directs the compiler to generate faster code. It no longer inlines methods across classes, or implicitly turns -depend on or -g off. Because it no longer implicitly turns on -depend, you need to add -depend to the command line where desired.

  2. Use only versions of javac released after JDK 1.1.4 to compile against Java 2 SDK for Solaris class files. JDK 1.1 versions of javac sometimes generate incorrect inner class attributes (the Java 2 SDK for Solaris javac generates correct attributes). The JDK 1.1.4 javac compiler and earlier compilers could crash when encountering the correct form. Beginning with JDK 1.1.5, javac handles both the old and the new corrected attributes. This is only a compile-time problem. Java 2 SDK for Solaris compiler generates class files that work on older VMs.

  3. Java 2 SDK for Solaris replaces the javakey tool with the keytool, PolicyTool, and jarsigner tools. See the Java 2 SDK for Solaris security documentation at http://java.sun.com/products/jdk/1.2/docs/guide/security/index.html for descriptions of the new tools.

  4. In JDK 1.1, javap -verify performed a partial verification of the class file. Java 2 SDK for Solaris does not include this option. The option was misleading because it did not perform many portions of a full verification.

  5. Prior to JDK 1.1.4, the Java interpreter allowed the class file at /a/b/c.class to be invoked from within the /a/b directory by the command java c (even if the class c was in package a.b.*). In JDK 1.1.4 and Java 2 SDK for Solaris, you must specify the fully qualified class name. For example, to invoke the class a.b.c at a/b/c.class, you could issue the command java a.b.c from the parent directory of directory /a.

  6. Because of bugs in JDK 1.1-based releases, code signed using the JDK 1.1 javakey tool appears to be unsigned to the Java 2 SDK for Solaris. Code signed using Java 2 SDK for Solaris appears to be unsigned to JDK 1.1-based releases.

  7. Prior to Java 2 SDK for Solaris, javac permitted some inconsistent or redundant combinations of command line options. For example, you could specify -classpath multiple times with only the last usage taking effect. You can no longer use this behavior.

  8. Prior to Java 2 SDK for Solaris, the -classpath option of the Java interpreter set the search path used by the VM when loading system classes. The VM then set the java.class.path property to reflect this path. Typically, application classes were invoked directly from the system class path without an associated class loader.

    Java 2 SDK for Solaris now starts applications in an application class loader to take advantage of both installed extensions and the new security model. The -classpath option now sets the classpath used by the application class loader (for loading classes and resources). Similarly, the java.class.path property now reflects this path. You can still override the system classpath used internally by the VM with a new -Xbootclasspath option. In most cases, you should not have to change the system classpath.

    Most applications should not be affected by this change. However, the java.class.path property no longer include those directories and JAR files used for loading system classes. Read the new sun.boot.class.path property for that information. Applications that install their own security managers might be adversely affected. You have to rewrite these applications for Java 2 SDK for Solaris, but in the meantime, the -Xbootclasspath switch is provided for backward compatibility.

  9. The Java 2 SDK for Solaris javadoc tool produces filenames of the form

    package-<package name>.html

    instead of the previous

    Package-<package name>.html

    for package-level API output. For example, previously the default package-level output for package java.io was in file

    Package-java.io.html

    beginning with Java 2 SDK for Solaris, the filename is

    package-java.io.html.

  10. The Java 2 SDK for Solaris javah is different as NMI is not supported, thus the -nmi flag is no longer provided. For more information, see "javah".

Serialization Incompatibilities

Because of rare and infrequent problems with the format for Externalizable objects, it was necessary to make an incompatible change in Java 2 SDK for Solaris. A JDK 1.1.5 (or earlier) program throws a StreamCorruptedException when it tries to read an Externalizable object generated in Java 2 SDK for Solaris format. Programs based on JDK software version JDK 1.1.6 or later do not have this problem.

However, a new Java 2 SDK for Solaris API supports backward compatibility. To write streams in the old format, before doing any writes, call


ObjectOutputStream.useProtocolVersion(PROTOCOL_VERSION_1)