Skip navigation.
Downloads | Product Documentation | Support

Migration Guide

# Best Coding Practices for JVM Migration

This section contains guidelines for writing applications to run on WebLogic JRockit SDK. This information provided here is in no way complete; it merely helps you avoid some common pitfalls. BEA Systems does not want to compromise Java's "write once run everywhere" notion. On the contrary, this sections highlights guidelines that are valid for any Java program. They are, however, especially important when switching between JVMs in general and between Sun Microsystem's HotSpot JVM and WebLogic JRockit JVM in particular.

The best coding practices are summarized in the following subjects:

- Read the Relevant Specifications
- Never Use Deprecated Unsafe Methods
- Minimize the Use of Finalizers
- Don't Depend on Thread Priorities
- Don't Use Internal sun.* or COM.jrockit.* Classes
- Override java.Object.hashCode for User Defined Classes When Using java.util.Hashtable
- Do Careful Thread Synchronization
- Expect Only Standard System Properties
- Minimize the Number of Java Processes
- Avoid Calling System.gc()

# Read the Relevant Specifications

Read the Java language specification and Java API specification carefully and do not rely on unspecified behavior.

A WebLogic JRockit JVM is based on a number of specifications; for example, The Java Virtual Machine Specification and the Java API Specification. You should be aware that many implementations of these specifications exist: WebLogic JRockit is one. You should never expect any particular behavior that is not specified in one of these documents. Unspecified behavior might differ between the Sun JVM and WebLogic JRockit JVM. Note too that behavior is sometimes different between individual releases of the Sun JVM and can also change between releases of WebLogic JRockit JVM.

You can find these specifications at the following sites:

- The Java Language Specification

>     http://java.sun.com/docs/books/jls/second_edition/html/j.title.doc.html

- Java 2 Platform API Specification,

>     http://java.sun.com/j2se/1.4.1/docs/api/index.html

- The Java Virtual Machine Specification

>     http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.
>        html

The specifications are written to give JVM vendors freedom to optimize their JVMs, and therefore they leave certain behavior unspecified. You should understand, however, that numerous parts of the specifications mentioned above are unspecified. The following examples describe three of these unspecified elements.

## Example 1: Reflection

The Java API Specification of the method `getMethods()` on the `java.lang.Class` class clearly states: "The elements in the array returned are not sorted and are not in any particular order."

## Example 2: Reflection Revisited

The `toString()` method of the `java.lang.reflect.Method` might include the access modifier `native`. Therefore, you should not rely on the result of this call to be equal between JVM implementations. Some classes in the Java API specification are implemented as `native` either by WebLogic JRockit JVM and the Sun JVM. There is no guarantee that a native implementation on one JVM has to be native on another one.

## Example 3: Serialization

The Java API Specification of the method `defaultReadObject()` of the `java.lang.ObjectInputStream` class does not specify the order in which fields are de-serialized; hence no such order can be expected.

# Never Use Deprecated Unsafe Methods

The deprecated methods

- `java.lang.Thread.stop`
- `java.lang.Thread.suspend`
- `java.lang.Thread.resume`
- `java.lang.Runtime.runFinalizersOnExit`

are inherently unsafe, and should never be used. For more information see:

>     http://java.sun.com/j2se/1.4/docs/guide/misc/threadPrimitiveDeprecation.html

# Minimize the Use of Finalizers

Finalizers are often error prone since they often implicitly depend on the order of execution. This order differs amongst JVMs, and between consecutive runs on the same JVM. Using finalizers is also inherently bad for performance since it imposes an additional burden on the memory management system that needs to handle execution of finalizers and let objects live longer. For more information on using—and not using—finalizers, please refer to:

http://access1.sun.com/techarticles/weak.references.html

http://www.memorymanagement.org/glossary/r.html#reference.object

# Don't Depend on Thread Priorities

Be careful when using `java.lang.Thread.setPriority`. Depending on thread priorities might lead on unwanted or unexpected results since the scheduling algorithm might choose to starve lower priority threads of CPU time and never execute them. Furthermore the result might differ between operating systems and JVMs.

The Java API specification states that "Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority."

The priority set by the `setPriority()` method is a parameter that might be used in the thread-scheduling algorithm, which shares CPU execution time between executing threads. This algorithm might be controlled either by the JVM or by the operating system. It is important to be aware of the fact that this algorithm normally differs between operating systems and that the algorithm might change between releases of both the operating system and the JVM. For WebLogic JRockit JVM native threads, the algorithm is implemented by the operating system; for thin threads it is implemented by the WebLogic JRockit JVM (it is partly controlled by the operating system since thin threads runs on top of operating system threads or lightweight processes).

# Don't Use Internal sun.* or COM.jrockit.* Classes

The classes that WebLogic JRockit SDK includes fall into package groups `java.*`, `javax.*`, `org.*`, `sun.*` and `COM.jrockit.*`. All but the `sun.*` and `COM.jrockit` packages are a standard part of the Java platform and will be supported into the future.In general, non-standard packages, which are outside of the Java platform, can be different across JVM vendors and OS platforms (Windows, Linux, and so on) and can change at any time without notice with SDK versions. Programs that contain direct usage of the `sun.*` and `COM.jrockit.*` packages are not 100% Pure Java.

For more information, please refer to the note about `sun.*` packages at:

>     http://java.sun.com/products/jdk/faq/faq-sun-packages.html

# Override java.Object.hashCode for User Defined Classes When Using java.util.Hashtable

On WebLogic JRockit, the current default implementation of hashCode returns a value for the object determined by the JVM. The value is created using the memory address of the object. However, because this value can be reused if the object is moved during garbage collection, it is possible to obtain the same hash code for two different objects. Also, two objects that represent the same value are guaranteed to have the same hash code only if they are the exact same object. This implementation is not particularly useful for hashing; therefore, derived classes should override `hashCode()`.

# Do Careful Thread Synchronization

Make sure that you synchronize threads that access shared data. Synchronization bugs often appear when changing JVMs because the implementation of locks, garbage collection, thread scheduling and so on, might differ significantly.

# Expect Only Standard System Properties

When implementing `java.lang.System.getProperties()` or `java.lang.System.getProperty()`, you should only depend on standard system properties being returned; different VMs may return a different set of extended properties. Non-standard properties should not be returned.

When the JVM starts, it inserts a number of standard properties into the system properties list. These properties, and the meaning of their values, are listed in the Java API specification. Do not expect any other non-standard properties.

>     http://java.sun.com/j2se/1.4/docs/api/java/lang/System.html#getProperties()

# Minimize the Number of Java Processes

When designing applications there is sometimes a choice between running several processes, i.e. JVM instances versus running several threads or thread groups within a single process, i.e. JVM instance. If possible, it is more effective to use as few JVM instances as possible per physical machine.

# Avoid Calling System.gc()

Don't call `java.lang.System.gc()`. This method behaves differently with WebLogic JRockit than with other JVMs. Instead of doing a complete garbage collection, as with the Sun JVM and others, when called by an application running with WebLogic JRockit, `System.gc()` behaves depending upon the garbage collector already in use:

- If you're using a generational copy collector, `System.gc()` does a collection in their nursery.
- For all other collectors, it does a collection only if one is needed. In other words, it does nothing special on the call.

The WebLogic JRockit JVM garbage collector will generally do a much better job of deciding when to do garbage collection than will `System.gc()`. If you are having problems with memory usage, pause times for garbage collection, and so on, you are better off configuring the WebLogic JRockit JVM memory management system appropriately. See uning WebLogic JRockit JVM in the Tuning WebLogic JRockit 8.1 JVM.