Tuesday Feb 17, 2009

JavaFX Book Coming to a Theatre Near You

Despite the considerable attention JavaFX has garnered, publications (i.e. books) that discuss JavaFX in any detail are few and far between, and anything that has been published, as good as it may have been, is unfortunately hopelessly out of date.  The reality is that up until recently, the JavaFX platform has been a moving target.  With the advent of JavaFX 1.1 however, the platform has stabilized to the point where you should begin to see legitimate books appearing on the subject.

Jim Clarke, Eric Bruno and I have been working steadfastly on a book entitled JavaFX: Developing Rich Internet Applications, which should be among the first -- if not the first -- of these new books.  From our standpoint the content is nearly finished.  What remains is the editing and publication process which takes a few additional months to complete.  Plans call for this book to be available in time for the JavaOne 2009 Conference, if not earlier.

We also plan on making rough cuts of certain chapters available on Safari.  As soon as these are ready, we'll let you know.  Finally, check out our website, jfxbook.com, dedicated to the book.  There you will find additional resources that accompany the book, including sample code and applications.  One such application is a JavaFX version of the popular Sudoku game, pictured below.

Visit jfxbook.com and give it a try.

Wednesday Jan 14, 2009

Overhead in Increasing the Solaris System Clock Rate

In a previous entry entitled Real-Time Java and High Resolution Timers, we discussed how Sun's Java Real-Time System requires access to timers with a resolution greater than the default 10ms to do anything really interesting.   It was also stated that most modern processors have an APIC or Advanced Programmable Interrupt Controller which supports much finer-grained clock tick rates.

Unfortunately there are many instances where a system does indeed contain an APIC, but it is not exposed by the BIOS.  Furthermore, we've found that some of the embedded, low-power x86-based processors do not contain an APIC at all.  For an example, take a look at the AMD Geode LX 800 based fit-PC Slim.

So if you wanted to utilize higher resolution timers for this class of system, you'd have to resort to alternative methods.  Solaris and OpenSolaris provide two /etc/system parameters called hires_tick and hires_hz to facilitate increasing your default system clock tick.  By adding the following line to /etc/system, you'll increase the system clock tick rate from the default of 100 per second to 1,000 per second, effectively changing the clock resolution from 10ms to 1ms.

   set hires_tick=1

If you want to further increase the clock resolution, you can do so via the hires_hz system tunable parameter.  Although formally unsupported, it does work.   In order to, for example, increase the clock tick rate to 10,000, add this to /etc/system:

    set hires_tick=1
    set hires_hz=10000

To achieve the desired effect above, you must include both the hires_tick assignment in addition to setting the hires_hz parameter.

These modifications do not come without side-effects, and depending upon the hardware in question and the granularity of the desired timer resolution, they could be significant.  In short, it takes additional CPU cycles to field all those timer interrupts.  So I thought it'd be interesting to see what effect changing the clock tick rate had on two separate systems.   Here they are:

 System  fit-PC Slim
 Panasonic Toughbook CF-30 (Revision F)
 CPU  AMD Geode LX 800 (500 Mhz)
 Intel Core 2 Duo L7500 1.60GHz
 OpenSolaris Version
 snv_98  snv_101b

The measuring tool used for this simple experiment is vmstat(1m).  Solaris aficionados will likely point out that there are much more accurate alternatives, but I think vmstat(1m) gives a decent feel for what's going on without having to expend a whole lot of extra energy.  In particular we'll look at the following fields returned by issuing a 'vmstat 5', and picking one of the interim samples:

  • in - interrupts per second
  • us - percentage usage of CPU time in user space
  • sy - percentage usage of CPU time in system space
  • id - percentage usage of CPU time idling

The sum of (us + sy + id) should approximate 100%.  The table below shows sample vmstat output on various clock tick settings for our two hardware platforms.

Clock tics/sec
 1000  10000  100000
/etc/system settings
 none (default)
 set hires_tick=1
set hires_tick=1
set hires_hz=10000
set hires_tick=1
set hires_hz=100000
vmstat(5) sample fit-PC
 in: 201
 us: 0
 sy: 1
 id: 99
 in: 2001
 us: 0
 sy: 5
 id: 95
 in: 19831
 us: 0
 sy: 43
 id: 57 

vmstat(5) sample CF-30

 in: 471
 us: 0
 sy: 0
 id: 99
 in: 2278
 us: 0
 sy: 1
 id: 99
 in: 20299
 us: 0
 sy: 5
 id: 95
 in: 200307
 us: 0
 sy: 21
 id: 79


  • The vmstat(5) was let run for about a minute.  The output above shows one of the typical 5 second samples.  The other 5 second samples are almost identical.
  • The user (us) CPU time numbers give us a reasonable idea that these systems were predominantly in an idle state when being sampled.
  • The number of interrupts serviced per second is directly proportional to the clock tick rate.
  • And of course, the larger the number of interrupts, the more system CPU time is required.
  • The amount of overhead taken up by increasing the clock rate is a function of system capability.  The CF-30 not only has a much faster processor, it also has two cores to share the interrupt load.  As such it could accommodate a much higher clock tick rate.  For the fit-PC, performance is impacted profoundly even at modest clock tick rates.

Thursday Dec 04, 2008

Why JavaFX is Relevant

This week marks the formal release of JavaFX 1.0.  During the interval between the early marketing blitz and now, we've heard a lot from our friends in the press and the blogosphere, and in many instances what they had to say was not very pretty.  Some think the Rich Internet Application platform battle lines are already drawn between Adobe and Microsoft, and dismiss Sun as having arrived too late to the party.  Others opine that JavaFX's underlying Java platform is so yesterday.  In fact Java is the primary reason why JavaFX will, much to the chagrin of many, receive serious consideration.  Here's why:

  • Java is ubiquitous.  It is the proven, de-facto platform for web-based deployment.  On the desktop, it is estimated that approximately 90% of PCs have Java installed. In fact the major PC OEMs have seen fit to install it for you out of the box.  In the mobile world, Java is the dominant deployment platform.  Billions (that's with a 'b') of devices run Java.
  • The Java development community is arguably the largest on the planet.  Java gained initial widespread acclaim as a productive development environment, and continues to do so.  As JavaFX is an evolution of Java and seamlessly integrates with it, human nature tells us that individuals will naturally want to work with and leverage that which they already know and are familiar with.
  • Alternatives are still no match for the Java Virtual Machine.  It has been extensively studied, vetted, scrutinized, poked, prodded, abused, cloned, and optimized more than any other virtual machine in the history of computing. And just in case you're under the impression that the Java Virtual Machine is limited only to the Java (and now JavaFX script) programming languages, think again.  At last count there were over 200 projects integrating modern dynamic languages to the Java VM.  That list includes the usual suspects like PHP, Ruby, JavaScript, Python, and [insert your favorite language here].
  • The amount of Java Standard Edition online updates is staggering.  We know.  We supply the downloads.  And once a desktop is upgraded, it will be able to take full advantage of the features JavaFX brings to the table, effectively trivializing the barriers to entry.
Many of our most talented folks have been working feverishly to reach this milestone.  That being said, there's still lot's more work to do.  But we're off to a real nice start.  Check out http://javafx.com.  Hmm.  looks like the site is a little sluggish right now.  Maybe we underestimated all the interest?

Wednesday Nov 05, 2008

OpenSolaris on the Smallest System Yet?

One of my compadres forwarded me this link from CompuLab, an Israeli company which has created this real small, very energy efficient PC.  It may just be the smallest full-featured system to date. 

I'm a sucker for these types of things, and thought it would be interesting to get a reduced footprint version of OpenSolaris up and running on it.  Haven't gotten around to playing with wi-fi, or for that matter the graphics (as the reduced footprint version of OpenSolaris has no windowing system), but every indication points to a system that doesn't require any magic incantations to get OpenSolaris up and running.  Here are some of the specs

CPU: AMD Geode LX800 500MHz     
Chipset: AMD CS5536
Display: Integrated Geode LX display controller up to 1920x1440  
Memory: 512MB DDR 333MHz soldered on-board
Hard disk: 2.5” IDE 60GB
 RJ45 Ethernet port 100Mbps
 WLAN 802.11b/g 54Mbps
 3 x USB 2.0 HiSpeed 480Mbps
 mini RS-232 (cable available from CompuLab)
 Stereo line-out audio (headphones)
 Stereo line-in audio / Mic

The system has a serial port, and upon request, CompuLab will provide the required custom serial cable.  By instructing GRUB to redirect the console to the serial port, you can connect the serial cable to another system and communicate directly with the console.  To get a rough idea of how to accomplish this, check here.  The screenshots below show that from an OpenSolaris terminal window, you can use the tip(1) command to accomplish this.

So the question is, how minimal is this configuration?  Issuing `ps -ef' shows that only 14 processes are currently running, of which I'm sure there's an opportunity to eliminate one or two if need be.

To give you an idea of how much RAM is currently consumed, here's what issuing the 'memstat' macro under mdb(1m) yields:

Who says Solaris can't fit in small places?

Wednesday Jul 23, 2008

Fast Booting Solaris

A veteran Java ONE keynote presenter, Perrone Robotics has developed some real interesting technologies which take the concept of using autonomous (i.e. unmanned) vehicles to a whole new level.  One of their key ingredients is the MAX software platform which utilizes common commercially available components to enable Perrone to very quickly and cost-effectively retrofit nearly any vehicle in short order.

The MAX robotics platform runs on a (roughly 4" x 6") low-power PC board atop Solaris and Sun's Java Real-Time System (Java RTS).  This combination gives Perrone the ability to leverage the huge Java development community, and assures that their critical software components behave in a predictable and deterministic fashion.

During the Java ONE 2007 conference, I was speaking with Paul Perrone about the notion of creating a minimized version of Solaris over which his platform might run.  The helicopter pictured above, boots from a relatively small (4-8Gb)  IDE flash drive, where standard Solaris takes up a substantial chunk.  It leaves them precious little space to collect valuable information like telemetry or terrain data.  Paul asked to revist this idea for a future project.  That's where we left off.

Not that we've ignored them since, but it wasn't until a year later that small Solaris reared its head again.  In addition to saving space, their main interest in this environment was in seeing how much faster Solaris might boot up.  The ability to be fully functional from power-up in as short a time as possible is of critical importance.

So before investigating what advantages there might be, let's provide some background information:


Two separate systems were used, and for argument's sake, represent two ends of the x86 compute spectrum. 

Embedded Profile
Modern Profile 
System iGologic i84810
Panasonic Toughbook CF-30 (Rev. F)
CPU 1GHz Celeron M
Core 2 Duo L7500 1.60GHz
Disk 4GB Flash IDE Drive
Solid State SATA Drive

Operating Systems

Minimal configurations were created for Solaris 10 08/07 (Update 4) and OpenSolaris Nevada build 93.  These configurations boot entirely into RAM and consume less than 100MB ramdisk space.  With a little more effort they can be may significantly smaller.  The original blog post describing the environment is here.   You can download the framework for these hardware/OS combinations here, and can get a feel for the build environment by taking a look at this README.


Within the context of this discussion, here are the key terms along with their meanings.

Total Boot Time: This is the time it takes from power-up till a user is prompted to log in.  Typically for a full Solaris installation, the windowing system must first start up and present the user with a login screen.  In a minimal Solaris environment, there is no windowing system.  Instead, the total boot time is defined as the time it takes from power-up till a user is prompted with the console login: prompt.

POST Time: POST or Power On Self Test is the time taken by the system at pre-boot to handle things like diagnostics,  BIOS and device initialization.  For this discussion, we'll define POST time as the time it takes from power-up until the user is presented with a GRUB boot menu.  We call out this segment of the total time because in many cases we are at the mercy of the PC/BIOS manufacturer and can't overly influence how quickly or slowly this proceeds.

Solaris Boot Time: The time it takes from being presented with a GRUB boot menu till a Solaris user is prompted to log in.  Again, depending upon whether a windowing system is configured or not, this may represent the time it takes to be prompted with a login screen or console login: prompt respectively.  This represents the segment of time that we can influence.

We can conclude from these definitions that:

   Total Boot Time = POST Time + Solaris Boot Time


Embedded Profile: iGoLogic i84810 system 

Post Time
Solaris Boot Time
Total Boot Time
 Solaris 10 08/07
13 sec
26 sec
39 sec
 OpenSolaris Nevada Build 93
13 sec
18 sec
31 sec 

Modern Profile: Panasonic Toughbook CF-30

Solaris Boot Time
 Total Boot Time
 Solaris 10 08/07
 6 sec
 18 sec
 24 sec
 OpenSolaris Nevada Build 93
 6 sec
 9 sec
 15 sec


1. These times were taken by hand with the stopwatch feature on my Timex.  If anything, the times might be slightly shorter than actually recorded as there is a human delay in reacting to seeing the necessary prompts.  I ran the tests several times, and the same numbers consistently appear.

2. The version of the OS appears to matter a lot, as OpenSolaris nvx_93 boots up nearly twice as fast as Solaris 10 U4 on the same hardware.

3. The type of I/O device subsystem seems to be a big factor too.  For example, by switching out the IDE Flash Drive with a 5400 RPM IDE hard disk, i84810 total boot time decreased by about 6 seconds for both Solaris 10 and OpenSolaris. 

4. The minimal Solaris environment is currently only available in 32-bit mode.

5. With relative ease, Solaris can be configured to boot in less that 10 seconds on modern x86 hardware.  My unofficial record stands at 9 seconds (or slightly less).   No doubt it could boot faster on more robust hardware (eliminating POST time).  Any takers?

Tuesday Jun 17, 2008

Real-Time Java in a Zone

As is often the case, Sun's technologies and offerings are being applied in ways which we hadn't necessarily anticipated.  Yet another example has reared its head in the govenrment/military space where customers have expressed interest in using Sun's Java Real-Time System with Solaris Trusted Extensions.  As it stands right now, Java RTS will neither operate nor install within the confines of such an environment.  Let's investigate why this is so, and see what current opportunities there are for working around this shortcoming.

So what is it that causes Trusted Extensions and Java RTS not to play together nicely?   It happens to revolve around Trusted Extension's extensive usage of Solaris zones to limit access between differing security levels.  Solaris packages must be specifically configured to accommodate zones, which has yet to formally take place with Java RTS.  As zones are a core component of Solaris, we can, for the sake of simplicity, just use standard Solaris to demonstrate how we can work around this temporary limitation.  These modifications should apply to Trusted Extensions just as well.   To get Java RTS to work within a zone, follow these steps:

1. Install the Java RTS cyclic driver (only) in the global zone.

global# pkgadd -d . SUNWrtjc

Processing package instance <SUNWrtjc> from </cyclic/src/packages_i386>
## Installing package <SUNWrtjc> in global zone

Java Real-Time System cyclic driver(i386) 2.1.0,REV=2008.
Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.
Using </> as the package base directory.
## Processing package information.
## Processing system information.
   5 package pathnames are already properly installed.
## Verifying package dependencies.
## Verifying disk space requirements.
## Checking for conflicts with packages already installed.
## Checking for setuid/setgid programs.

This package contains scripts which will be executed with super-user
permission during the process of installing this package.

Do you want to continue with the installation of <SUNWrtjc> [y,n,?] y

Installing Java Real-Time System cyclic driver as <SUNWrtjc>

2. Create a zone called 'rtjzone':
global# mkdir -p /zone
bash-3.00# zonecfg -z rtjzone
rtjzone: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:rtjzone> create
zonecfg:rtjzone> set zonepath=/zone/rtjzone
zonecfg:rtjzone> verify
zonecfg:rtjzone> commit
zonecfg:rtjzone> exit
global# zoneadm list -vc
  ID NAME             STATUS     PATH                           BRAND    IP
   0 global           running    /                              native   shared
   - rtjzone          configured /zone/rtjzone                  native   shared
global# zoneadm -z rtjzone install
Preparing to install zone <rtjzone>.
Creating list of files to copy from the global zone.
Copying <6984> files to the zone.
Initializing zone product registry.
Determining zone package initialization order.
Preparing to initialize <1074> packages on the zone.
Initialized <1074> packages on zone.
Zone <rtjzone> is initialized.
Installation of <1> packages was skipped.
The file </zone/rtjzone/root/var/sadm/system/logs/install_log> contains a log of the zone installation.

3.  Modify the zone to allow access to the cyclic device, and to allow additional privileges

global# zonecfg -z rtjzone
zonecfg:rtjzone> set limitpriv=default,proc_priocntl,proc_lock_memory,proc_clock_highres
zonecfg:rtjzone> add device
zonecfg:rtjzone:device> set match=/dev/cyclic
zonecfg:rtjzone:device> end
zonecfg:rtjzone> verify
zonecfg:rtjzone> commit
zonecfg:rtjzone> exit

global# zoneadm -z rtjzone reboot
Note:  One privilege that is useful with Java RTS is sys_res_config.  This is typically used to assign a real-time process to a processor set.  Unfortunately zones cannot currently be given this privilege.  You can however, from the global zone, assign a processor set to a zone, which might be a reasonable workaround.

4.  Get a copy of the SUNWrtjv package and modify it so that it will install in a zone.  The postinstall script and postremove script must replaced with those provided by these hyperlinks just mentioned.

rtjzone# cd /scratch
rtjzone# ls
SUNWrtjv	postinstall	postremove
rtjzone# cp postinstall SUNWrtjv/install/
rtjzone# cp postremove SUNWrtjv/install/

5. Modify the SUNWrtjv pkgmap file with the appropriate sizes, checksums and last access dates.  The source code for a sample C program, called pkgmap_info, which prints out the necessary information, can be found here.

rtjzone# cd SUNWrtjv
rtjzone# grep post pkgmap 1 i postinstall 5402 42894 1194344457 1 i postremove 2966 34854 1194344457 rtjzone# cp pkgmap_info.c /tmp rtjzone# cc -o /tmp/pkgmap_info /tmp/pkgmap_info.c rtjzone# cd /scratch/SUNWrtjv/install/ rtjzone# /tmp/pkgmap_info postinstall postinstall 5820 9488 1213727841 rtjzone# /tmp/pkgmap_info postremove postremove 3092 45039 1213727538
Replace the postinstall and postremove entries in the pkgmap file with those produced by the pkgmap_info program.  You cannot simply use the example data above because the last access times will not match.  Doing so will cause the install to fail.

6. Install the Java RTS SUNWrtjv package inside the zone.

rtjzone# cd /scratch
rtjzone# pkgadd -d . SUNWrtjv

Processing package instance <SUNWrtjv> from </scratch>

Java Real-Time System runtime environment(i386) 1.5.0_13_Java-RTS-2.0_01-b08_RTSJ-1.0.2,REV=2007.
Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.

Where should this package be installed? (/opt): /opt

To achieve predictable temporal behavior, the Java Real-Time System
must be granted access to a number of privileged Solaris resources.
By default, access to these privileged resources is only granted to
the superuser (root). They can also be granted to additional users
by creating a rights profile, that is, a collection of authorizations,
that can later be assigned to an administrative role or directly
to a user.

As part of this package installation, a local 'Java Real-Time System User'
rights profile can be created on this machine.
This rights profile should NOT be created if such an action conflicts
with your computer security management policies. If unsure, contact
your system administrator or your computer security manager.
Also refer to the product's release notes for further details regarding
the privileges required by the Java Real-Time System.

Should a local 'Java Real-Time System User' rights profile be created? [y,n] (no): y
Using </opt> as the package base directory.
## Processing package information.
## Processing system information.
## Verifying package dependencies.
## Verifying disk space requirements.
## Checking for conflicts with packages already installed.
## Checking for setuid/setgid programs.

This package contains scripts which will be executed with super-user
permission during the process of installing this package.

Do you want to continue with the installation of <SUNWrtjv> [y,n,?] y


## Executing postinstall script.
Creating the 'Java Real-Time System User' rights profile.

Refer to the 'System Administration Guide: Security Services'
documentation for further information regarding the way to assign the
'Java Real-Time System User' rights profile to users, groups, or
administrative roles using the Solaris Management Console, smc(1M) or
the usermod(1M), groupmod(1M) and rolemod(1M) commands.

Installation of <SUNWrtjv> was successful.

6.  Try running a real-time Java application in the zone.

rtjzone# /opt/SUNWrtjv/bin/java -version
java version "1.5.0_13"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13_Java-RTS-2.0_01-b08_RTSJ-1.0.2)
Java Real-Time System HotSpot(TM) Client VM (build 1.5.0_13-b08, mixed mode)

We hope to more formally support Solaris zones usage with Java RTS in the future.  In the interim this workaround can help you get started.  Many thanks to Jim Clarke, who did the lion's share of the legwork to find this solution.

Thursday May 29, 2008

Are Solaris RAM Disks Swappable?

As memory access is typically orders of magnitude faster than disk access, the idea of using a part of RAM as an in-memory storage device has been one of the earliest performance optimizations realized by the computer science community.  Even though today this type of optimization takes place transparently inside modern operating systems (via mechanisms like the disk buffer cache),  there are still circumstances where manually creating a RAM disk might still be quite useful.

A Solaris customer using the ramdiskadm(1m) utility to create a Ram disk device for a real-time application posed the following question: "Are RAM disks swappable?". From a real-time perspective, a RAM disk not only yields significantly better seek performance but also provides for more deterministic behavior compared to the traditional rotating disk platter.  The customer's concern here is that, under dire circumstances, is it possible for operating system swap out the RAM disk memory?  Needless to say, if a swap out occurred it would put a big crimp in the real-time application's predictability.

To get an idea of what's going on when a RAM disk is created, let's use the Solaris kstat(1m) kernel statitics utility to see how memory is being allocated.  First let's see what memory looks like before creating a RAM disk:

# pagesize
# kstat -n system_pages | grep pagesfree
       pagesfree                       96334
# kstat -n system_pages | grep pageslocke      pageslocked                     26170

So, on this particular system, where a page is 4096 bytes,  there are currently 96334 pages free, and 26170 pages that are locked.  Now let's create a 50MB RAM disk:

# ramdiskadm -a rd 50m
# ramdiskadm
Block Device                                                  Size 
/dev/ramdisk/rd                                           52428800    Yes 
# kstat -n system_pages | grep pagesfree
       pagesfree                       83507
# kstat -n system_pages | grep pageslocked
       pageslocked                     38988

Let's subtract the original number of pageslocked from the latest value and multiply by the pagesize:

# pagesize
# bc

The increase in locked pages can be attributed to the creation of the RAM disk (50m + a small amount of overhead).  So yes, these pages are locked into memory.  But it would be nice to get a definitive statement on what pageslocked actually means.  According to McDougal, Mauro and Gregg's Performance and Tools: DTrace and MDB Techniques for Solaris 10 and OpenSolaris, pageslocked is "Total number of pages locked into memory by the kernel and user processes".  Furthermore, the man page for plock(3C), a related library routine which enables programmers to lock memory segments, states that "Locked segments are immune to all routine swapping".  What's routine swapping?

Hmm.  Anybody care to shed some light on this?

Monday May 19, 2008

Working Around a Simple Directory Server Install Issue with Windows

While working with a customer evaluating Sun's Directory Server Enterprise Edition 6.3 for Windows, we came across a problem during very basic install and setup.  For posterity's sake, I thought it might make sense to document the issue and offer a few potential workarounds. 

How to replicate

1. Install the directory server.  In this case the downloadable image has been unzipped into the c:\\tmp\\dsee63\\DSEE_ZIP_DISTRIBUTION directory

  C:\\tmp\\dsee63\\DSEE_ZIP_Distribution> dsee_deploy --no-inter -i /tmp/ds63                                                                              
Unzipping sun-ldap-shared-l10n.zip ...
Unzipping sun-ldap-directory.zip ...
Unzipping sun-ldap-console-gui-help-l10n.zip ...
Configuring Cacao at /tmp/ds63/dsee6/cacao_2
You can now start your Directory Server Instances
You can now start your Directory Proxy Server Instances

2. Create a new Directory Server instance and start the instance

  C:\\tmp\\dsee63\\DSEE_ZIP_Distribution>cd \\tmp\\ds63
C:\\tmp\\ds63> set PATH=c:\\tmp\\ds63\\ds6\\bin;c:\\tmp\\ds63\\dsrk6\\bin;%PATH%
C:\\tmp\\ds63>dsadm create /tmp/instance
Choose the Directory Manager password:
Confirm the Directory Manager password:
Use 'dsadm start '/tmp/instance'' to start the instance
C:\\tmp\\ds63>dsadm start /tmp/instance
Waiting for Directory Server instance 'C:/tmp/instance' to start...
Directory Server instance 'C:/tmp/instance' started: pid=2144

3. Create a suffix.  This is where the installation fails:

C:\\tmp\\ds63>dsconf create-suffix -h localhost -p 1389 dc=example,dc=com
Enter "cn=Directory Manager" password:
Unable to bind securely on "localhost:1389".
The "create-suffix" operation failed on "localhost:1389".

The problem here is described in The Sun Java System Directory Server Enterprise Edition 6.3 Release Notes:

On Windows systems, Directory Server does not allow Start TLS by default.

This issue affects server instances on Windows systems only. This issue is due to performance on Windows systems when Start TLS is used.

To work around this issue, consider using the -P option with the dsconf command to connect using the SSL port directly. Alternatively, if your network connection is already secured, consider using the -e option with the dsconf command. The option lets you connect to the standard port without requesting a secure connection.


Two Potential Workarounds

Workaround 1: Issue the 'dsconf create-suffix' command by directly connecting to the SSL port (-P 1636)

C:\\tmp\\ds63>dsconf create-suffix -h localhost -P 1636 dc=example,dc=com
Certificate "CN=TECRA-A1, CN=1636, CN=Directory Server, O=Sun Microsystems" pres
ented by the server is not trusted.
Type "Y" to accept, "y" to accept just once, "n" to refuse, "d" for more details
: Y
Enter "cn=Directory Manager" password:

Workaround 2: Modify the ds-start-tls-enabled attribute that is stored in the directory server configuration.

a. Create a file, say c:\\tmp\\modify.ldif which looks like:

  dn: cn=config
  changetype: modify
  replace: ds-start-tls-enabled
  ds-start-tls-enabled: on

b. Issue an ldapmodify command something like this:

  C:\\tmp>ldapmodify -h localhost -p 1389 -D "cn=Directory Manager" -w password < c:\\tmp\\modify.ldif
modifying entry cn=config

c. Confirm modification via ldapsearch command:

  C:\\tmp>ldapsearch -b "cn=config" -h localhost -p 1389 -D "cn=Directory Manager" -w password "cn=config" ds-start-tls-enabled
version: 1
dn: cn=config
ds-start-tls-enabled: on

dn: cn=config,cn=chaining database,cn=plugins,cn=config

dn: cn=config,cn=ldbm database,cn=plugins,cn=config

c. Stop and restart the directory server instance

  C:\\tmp\\ds63>dsadm stop /tmp/instance
Directory Server instance 'C:/tmp/instance' stopped

C:\\tmp\\ds63>dsadm start /tmp/instance
Directory Server instance 'C:/tmp/instance' started: pid=3560

d. Try creating a suffix with the standard port (1389):

  C:\\tmp\\ds63>dsconf create-suffix -h localhost -p 1389 dc=example1,dc=com
Enter "cn=Directory Manager" password:

Note:  Directory Server Enterprise Edition 6.3 is supported on Windows Server 2003, but not for Windows XP.  Although not formally supported, it is possible to experiment with XP.

Tuesday May 06, 2008

Using Solaris to Burn the OpenSolaris 2008.05 CD Image

If you're using Solaris or OpenSolaris as a platform to download and burn the recently announced OpenSolaris 2008.05 image, the instructions found here may need a slight modification.  After downloading the Live CD, you are instructed to use the cdrw(1) command as follows to burn the image to CD:

cdrw -i /path/to/iso/image/os200805.iso

Here's what might happen on your system when you attempt to use the 'cdrw -i' command:

The cdrw(1) command fails because it thinks the ISO image is larger than the default capacity of the CD.  The solution to this problem is explained in these excerpts from the cdrw(1) man page:

"Most commercially available drives allow writing beyond 74 minutes as long as the media has the capacity (such as 80–minute media). However, the ability to write beyond 74 minutes might not be supported by the drive in use. If the drive supports this feature, then use the -C option to indicate that the tool should rely on the capacity indicated by the media.

"-C [option] Uses stated media capacity. Without this option, cdrw uses a default value for writable CD media, which is 74 minutes for an audio CD, 681984000 bytes for a data CD, or 4.7 Gbytes for a DVD." 
This time let's invoke 'cdrw' with the -C option.


Monday Apr 21, 2008

Modifying and Respinning a Bootable Solaris ISO Image

As an adjunct to the previous blog post, a slightly customized boot environment capable of enabling serial console kernel debugging was required to diagnose Solaris install problems.  The post itself mentioned that a nice way to accomplish this was to set up PXE network boot via Solaris jumpstart.  It is indeed flexible and enables one to experiment with modifications and quickly test whether they perform as expected.  The one downside to this environment is that an additional DHCP/TFTP boot server has to be configured.  To eliminate that service, you could, once the customizations are well understood, simply create a new version of the Solaris install DVD with your customizations.  Let's run through the process for a simple example.

1. Get a Solaris DVD.  For this example, we'll use an interim build of the upcoming Solaris 10 Update 5.

2. Extract the the entire contents of the DVD.

# lofiadm -a /export/iso/s10x_u5b10_dvd.iso
# mkdir -p /iso
# mount -r -F hsfs /dev/lofi/1 /iso
# cd /iso
# mkdir /export/modified-s10x_u5b10
# find . -depth -print | cpio -pudm /export/modified-s10x_u5b10
4516208 blocks

3. Modify the content contained in /export/modified-s10x_u5b10.  In this case, we'll change the boot/grub/menu.lst file found in this directory to look like:

#pragma ident "@(#)install_menu 1.1 05/09/01 SMI"
serial --unit=0 --speed=9600
terminal serial
title Solaris Serial Console ttya
kernel /boot/multiboot kernel/unix -B install_media=cdrom,console=ttya
module /boot/x86.miniroot

4. Issue the following magic incantation to create a bootable ISO image based on the contents of the /export/modified-s10x_u5b10 directory.

# mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -R -L -r -D -U \\
-joliet-long -max-iso9660-filenames -boot-info-table -o \\
/export/iso/modified-s10x_u5b10.iso /export/modified-s10x_u5b10


Size of boot image is 4 sectors -> No emulation
1.80% done, estimate finish Fri Apr 18 15:55:13 2008
2.25% done, estimate finish Fri Apr 18 15:59:07 2008
2.70% done, estimate finish Fri Apr 18 15:58:37 2008
3.15% done, estimate finish Fri Apr 18 15:58:48 2008

98.43% done, estimate finish Fri Apr 18 15:59:37 2008
98.88% done, estimate finish Fri Apr 18 15:59:37 2008
99.33% done, estimate finish Fri Apr 18 15:59:36 2008
99.78% done, estimate finish Fri Apr 18 15:59:36 2008
Total translation table size: 2048
Total rockridge attributes bytes: 3075577
Total directory bytes: 18921472
Path table size(bytes): 148014
Max brk space used 1b24000
1112471 extents written (2172 MB) 

Voila!  Acknowledgements to Tom Haynes and this blog post which served as an excellent guide.

Monday Apr 14, 2008

Enabling Remote Console Debugging of Solaris x86 Boot/Install

Our partners do a fair amount of business supplying ruggedized Solaris-powered Panasonic Toughbook computers to their US government/military customers.  As a regular part of the product cycle, Sun usually works with both the integrators and Panasonic to assure that as new models become available, Solaris runs on these systems properly.  Furthermore, when we can get our grubby little hands on the systems, we'll run them through our certification suite of tests and formally place them on the Solaris Hardware Compatibility List.  As an example, here's the certification report for one of the versions of the Panasonic Toughbook CF-29.

Panasonic recently introduced a new version of the Toughbook CF-30 (referred to as revision F) which tweaks some of the computer subsystems resulting in an all-too-familiar scenario: namely, these differences cause the current version of Solaris to fail to install.  Note: Solaris is not alone here, all Operating Systems must continually play this cat and mouse game to support the latest hardware/firmware advances.

Our initial hypothesis lead us to believe that the problem was related to the introduction of the Intel ICH8 SATA chipset.  So we called on some of our Solaris I/O experts, based out of Sun's Beijing office, to take a peek at what was going on.  As the laptop is currently in New York, we needed a way for folks half way around the world to have access to this system.  There are lots of mechanisms available to remotely diagnose systems, what's somewhat unique here is the following: (1) the diagnosis takes place very early in the boot stage, way before any windowing or networking is set up and (2) The system in question is a laptop, not a server, where things like Lights Out Management (LOM) service processors are non-existent.

The solution here was to utilize decades old RS-232 technology combined with some of features of the GRUB bootloader.  Here are two requirements needed:

  • A serial connection must be established between the system to be diagnosed, which will be referred to henceforth as the target, and the system which accesses the target which we'll refer to as the remote host.   Unfortunately most laptop manufacturers have seen fit to eliminate serial port connectors in lieu of using USB to serial converters as a replacement technology.  At the early stages of boot, USB/serial capability is not yet available, so these systems are not good candidates for this type of diagnosis.  Thankfully the target in question here, the Panasonic CF-30 Toughbook, still comes with a serial port.
  • A Jumpstart environment capable of installing Solaris on x86/x64 systems is strongly recommended.  As part of the process described below, we'll be modifying the target's GRUB environment  (menu.lst).  If you chose to use a DVD boot/install environment instead, you'd need to modify and burn a new DVD for each change made to the target's boot environment.  It took a bit of time to find the right incantations in the menu.lst file to get what was needed here; continually re-burning DVDs would have been excruciating.  This exercise is left to the reader, here's a good start to understanding the jumpstart setup process.

Here's how to set up the remote console environment:

1. A null modem cable must be physically connected between the remote host and target.  The most common cable required will be a DB-9 female-to-female connector.  Your configuration may vary.

2. Check the BIOS of the remote host and target and make sure serial ports are enabled.

3. Running Solaris on the remote host, we'll be using the tip(1) command to access the target via serial port.  Edit the /etc/remote file and look for the hardwire: entry.  Modify it to look like this:


4. As part of setting up a jumpstart install for the target, a series of files are created in the /tftpboot directory of the jumpstart server.  Under /tftpboot, there should be a custom menu.lst file for each managed install, suffixed by the unique network MAC address of the system in question.  For example, the network MAC address for the CF-30 in question is 0:b:97:db:c0:97.  The related /tftpboot file for the CF-30 turns out to be /tftpboot/menu.lst.01000B97DBC097. As your target will have a different MAC address, it's menu.lst  file will have a different suffix in the /tftpboot directory.  Edit that custom menu.lst file (for example, /tftpboot/menu.lst.01000B97DBC097) to look as follows:

serial --unit=0 --speed=9600
terminal serial
title Solaris_10 s10x_u5b10
kernel /I86PC.Solaris_10-1/multiboot kernel/unix -B console=ttya,install_media= -vkd
module /I86PC.Solaris_10-1/x86.miniroot

The key modifications here involve (1) inclusion of the serial --unit=0 --speed=9600 and terminal serial lines plus (2) additional arguments added to the kernel directive.  Grub is very fussy about the order and placement of arguments; playing around with these will likely change grub's behavior. 

5.  From the remote host, access the serial console of the target by issuing:

$ tip hardwire

6. Inside a terminal window, here's what the serial console looks like, after the system has been power cycled and runs through the POST sequence:

After the miniroot is loaded, you'll be presented with an mdb prompt and a screen which looks like this:

You can now issue mdb commands to diagnose.  In this scenario you should also be able to reboot the  system without any other manual intervention, like this:


Here's what issuing the mdb commands ':c' and '$c' look like in this environment.   From this simple  trace we can ascertain that the SATA drivers were never even loaded.  Turns out this is likely a VM problem.  Here's the filed bug report.

Wednesday Mar 26, 2008

Reduced Footprint Java SE: Bringing Java Standard Edition Down to Size

A previous blog post demonstrated how you can, with minimal effort, lessen the disk footprint of a typical Java SE 5.0 runtime environment by about a third without violating the Java Standard Edition Licensing agreement. That post focused primarily on removing optional files and compressing class library jar files.  It turns out that with a little more engineering,  there is significant opportunity for further space optimization.

These additional savings involve more intimate knowledge of the inner workings of Java SE.  Sun performs this engineering work and provides a series of reduced footprint versions of Java SE, in binary form, for some of the most common embedded platforms.  They include some of these enhancements:1

  • Headless configuration - The inclusion of graphics subsystems like AWT and Swing comprise a large chunk of the Java SE footprint.  If your device has no graphics capability (i.e. is headless) why would you need to include this functionality?  Headless configurations:
  1. Do not support keyboard or mouse input
  2. Cannot create windows or display graphics
  3. Throw a HeadlessException when a graphics API is called
  4. Still support a functional Java 2D API for printing and off-screen rendering
  5. Are still 100% Java SE compatible
  • Eliminate client or server compiler - Sun's Java SE implementations include two HotSpot compilers, tuned and designed for specific environments.  The client compiler focuses on things like fast user interactivity and quick startup, while the server compiler's priority is on optimizing large, long-lived server applications.  The Java SE VM can only use one of these compilers at a time, so removing the unused one can save considerable space.
  • Minimizes memory consumption - Standard Java SE allocates RAM to house things like the JIT code cache and the object heap.  By default, each one of these areas (and others) can be assigned 64 MB.  In an embedded platform where the total amount of RAM might only be 64MB, Java SE will simply not have enough memory to run.  Java SE Embedded on the other hand, will automatically adapt memory usage to the amount of available RAM.  Consequently, 64MB is a reasonable amount of RAM for a large set of embedded Java applications.
  • Space vs. speed tradeoffs - (1) Java SE implements a thread lookup table, which in layman's terms, helps save a few instructions when switching between Java threads.  By eliminating this table, a couple of MBs of RAM can be spared from your application's working set. (2) Java SE also sets aside an area (mmap'ed) for loading jar files into random access memory, which as was explained to me, may help performance, but may also result in duplicate copies of jar files in memory.  Removal of this area further reduces the Resident Set Size.

An Example

Following through with the exmaple in the last post., let's start with an unmodified version of Java SE 5.0 Update 13 for Linux/x86.  By default, the static footprint is approximately 88MB.

   jimc@jalopy:/tmp> du -sk ./jre1.5.0_13/
88185   ./jre1.5.0_13/

After following the directions in the previous post, we can pare it down to roughly 60MB.
   jimc@jalopy:/tmp> du -sk /tmp/jre1.5.0_13/
59358 /tmp/jre1.5.0_13/

Downloading Sun's reduced footprint version of Java SE for x86/Linux yields:

   jimc@jalopy:/tmp> du -sk /tmp/jre1.5.0_10/
31003 /tmp/jre1.5.0_10/

This version of the JRE is about one-third it's original size, and furthermore has been modified to use significantly less memory than the standard Java SE offerings.  Note: we are comparing slightly different updates of Java SE 1.5 (update 13 vs. update 10).  They are indeed not identical but their differences should be considered, for the sake of argument, negligible. 

[1] Many thanks to Bob Vandette, who though presentation and conversation, supplied this information.  One of many sources comes from Bob's Java ONE 2007 session called, Deploying Java Platform Standard Edition (Java SE Platform) in Today's Embedded Devices (TS-2602)

Thursday Feb 14, 2008

Reducing Your Java SE Runtime Environment Footprint (Legally)

Because the resource requirements for Java Standard Edition are by no means insignificant, developers interested in utilizing Java on smaller platforms have traditionally opted for one of the Java Micro Edition configurations.   It should therefore come as no surprise that some of the Standard Edition functionality has to be sacrificed in these constrained Java ME environments.  However, as the trend towards more capable devices continues, it becomes reasonable to once again consider the advantages of utilizing Java SE.  Unfortunately, with a static footprint that could easily exceed 100MB, Java SE may still be too large to swallow for a lot of applications.

It is duly noted that the criticism leveled at Sun for exacting too much control over the Java platform has been widespread.  Like it or not though, one benefit of Sun's initial stewardship has been that Java SE has remained a standard platform, and threats to splinter it have thus far been reasonably thwarted.  Accordingly, in order to avoid incompatibilities, there are restrictions spelled out in the Java SE Licensing Agreement which prohibit modification of the Java SE binary distribution.

That  being said, there are a list of optional files, specified by the Java Runtime Environment's README file which can be removed, without ramification, to lessen the footprint.  They include:

  • Deployment tools (e.g. Java Web Start, Java plugin)
  • IDL and RMI tools (e.g. rmid, tnameserv)
  • Security tools (e.g. policytool, keytool)
  • orbd
  • Localization (charsets.jar)

In addition, further space optimization can be achieved by compressing the class library files contained in the rt.jar file.  By default, Java SE ships this jar file uncompressed.  The tradeoff here is space vs. performance, i.e. the classloader must expend cycles to uncompress the Java classes as they are being loaded.

An Example

So let's download a sample JRE from java.sun.com and see how it's footprint can be minimized.   For this example, we'll use Java SE 1.5.0 Update 13 for Linux x86.

After installation, the JRE is approximately 88MB

   jimc@jalopy:/tmp> du -sk ./jre1.5.0_13/
88185   ./jre1.5.0_13/

Here's what it looks like after removal of the optional files

   jimc@jalopy:/tmp> cd jre1.5.0_13/

jimc@jalopy:/tmp/jre1.5.0_13> /bin/rm -rf lib/charsets.jar lib/ext/sunjce_provider.jar \\
lib/ext/localedata.jar lib/ext/ldapsec.jar lib/ext/dnsns.jar bin/rmid \\
bin/rmiregistry bin/tnameserv bin/keytool bin/kinit bin/klist bin/ktab \\
bin/policytool bin/orbd bin/servertool bin/javaws, lib/javaws/ and lib/javaws.jar

jimc@jalopy:/tmp/jre1.5.0_13> cd ..
jimc@jalopy:/tmp> du -sk ./jre1.5.0_13/
77227 ./jre1.5.0_13/

And after rt.jar has been compressed

   jimc@jalopy:/tmp> mkdir rtjar
jimc@jalopy:/tmp> cd rtjar/

jimc@jalopy:/tmp/rtjar> jar -xf /tmp/jre1.5.0_13/lib/rt.jar
jimc@jalopy:/tmp/rtjar> zip -q -r /tmp/rt .
jimc@jalopy:/tmp/rtjar> mv /tmp/rt.zip /tmp/jre1.5.0_13/lib/rt.jar

jimc@jalopy:/tmp/rtjar> du -sk /tmp/jre1.5.0_13/
59358 /tmp/jre1.5.0_13/


In many cases, you can lop off about a third of the Java Runtime Environment footprint with no ill effects.  In a future post, we'll discuss how Sun has further reduced Java SE significantly, not only from the point of view of static footprint, but also from a RAM usage perspective too.  For a preview you can check out Sun's Java SE Embedded technology.

Thursday Jan 31, 2008

Good Things Come To Those Who Wait

Java RTS 2.1 EA (Early Access) marks the arrival of a commitment made some time back, namely that Sun would provide a version of the Java Real-Time System for Linux.  Perhaps to some, it was long time in the making, but in fact there are at least 2 good reasons why a Linux version wasn't available till now:

  1. Until recently, there was no standard Linux release/kernel which had true real-time support.  Typically the versions available were non-standard and did not constitute any considerable volume.  Mainstream Linux distributions are only now incorporating the necessary real-time underpinnings.
  2. Porting the Java Real-Time System VM to additional platforms is non-trivial.

Support and testing for Java RTS 2.1 EA at this time is limited to the currently shipping SUSE Linux Enterprise Real Time10 platform and the upcoming Red Hat Enterprise MRG 1.0 release.  It is however possible that other versions of Linux could run Java RTS 2.1 EA as it utilizes the real-time POSIX programming interface.  At minimum they would require a 2.6.21 kernel or greater and a glibc of 2.5 or greater.  In addition, the latest RT patch would also be needed.

This announcement pertains only to Linux, but of course a 2.1 EA version for both Solaris x86/x64 and Sparc will be shortly forthcoming. In the interim, a version of Java RTS 2.0 update 1 is readily available.  Documentation for both Java RTS 2.0 and 2.1 EA can be found here.

Regardless of platform, an evaluation version of the software is available for download at the Java RTS download page.


Wednesday Dec 19, 2007

Java RTS 2.0 Update 1 Released

After blogging about the relationship between high resolution timers and Java RTS, a comment was posted by a reader stating that they couldn't use Java RTS 2.0 with the latest Solaris 10 update.  Unfortunately that reader was correct.

At the time of the post, Sun had released Solaris 10 Update 4, while Java RTS 2.0 would only support Solaris 10 update 3.  To further exacerbate the situation, once Sun releases a new version of Solaris, they do their best to encourage users to use the latest version by making it difficult (if not impossible) for them to locate previous update versions.

There is a dependency between the aforementioned high resolution timer interface and Solaris which is update specific.  We're working to rectify this situation, but as the process behind Solaris is deliberately bureaucratic, this might take a while.  In the interim we'll need to keep in better lock step with Solaris releases.

On November 27, Java RTS 2.0 update 1 was released: 

  • It supports the latest Solaris 10 update (called 08/07 or update 4)
  • Support for Java SE has been updated to Java SE 5 update 13
  • A new Java RTS DTrace Provider is available
  • Other enhancements are listed here



Jim Connors-Oracle


« March 2015