Pencarian

Rss Posts

 

 

 

Berita pada kategori ‘Pemrograman’

JSR 292 Goodness: Fast code coverage tool in less than 10k

Feb 12, 2011

JSR 292 introduces a new bytecode instruction invokedynamic but also several new kind of constant pool constants. Which means that most of the tools that parse bytecodes like ASM, BCEL, findbugs or EMMA will need to be updated to be java 7 compatible.
EMMA is a code coverage tool, a tool that helps developers to know if their tests cover all the code of the application. While it’s not the only code coverage tool available in Java, it’s the most popular from my personal experience.
In this blog entry, I would like to show how to write a simple code coverage tool indycov that use JSR 292 API to have a runtime overhead close to zero.

How a code coverage tool works ?

A code coverage tool records all paths taken when running the application and checks at the end if all lines of codes was recorded.
By example, if I run the code below with no argument, it will print "foo" and "bar" and the code coverage tool will say that the else branch that prints "baz" will be not covered.

public static void main(String[] args) {
    System.out.println("foo");
    if (args.length == 0) {
      System.out.println("bar");
    } else {
      System.out.println("baz");
    }
  }

To record if an instruction was executed or not, code coverage tools add a probe which is a small amount of bytecodes that will call the runtime of the tool to say: "I have visited this instruction".
In fact, tools, only add probes where necessary, at the begining of each basic block of the control flow. A basic block is a collection of instructions without any jump (return, thow, if, break etc).
By example, the code above has 4 basic blocks: the once printing "foo", the one printing "bar", the one printing "baz" and the one containing the return at the end of the method.

So a code coverge tool is a tool that find basic blocks and add probes at the begining of each one.

Using JSR 292 API to implement a code coverage tool.

Finding basic block is easy with bytecode that come from 1.6 or 1.7 compiler because the compiler is required to add stack maps
in the bytecode flow. Stack maps are used to verify the bytecode in linear time and are inserted at the join points of the control flow.
So finding basic block in a 1.7 compatible bytecode can be done in one pass thanks to the stack maps info inserted by the compiler.

All existing code coverage tools have an impact on the performance of the application because the code of the probe is executed each time you call a basic block even if it should be executed once.
If you are a regular reader of this blog, you already know how to create a probe that will be executed once. The trick is use use invokedynamic, to record the visit in the bootstrap method and
to use a target method handle that is equivalent to no-op. So subsequent call will not execute any code.

main([Ljava/lang/String;)V
    INVOKEDYNAMIC probe ()V [fr/umlv/indycov/RT#bsm, 1]
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "foo"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
    ALOAD 0
    ARRAYLENGTH
    IFNE L0
    INVOKEDYNAMIC probe ()V [fr/umlv/indycov/RT#bsm, 2]
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "bar"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
    GOTO L1
    L0
    FRAME SAME
    INVOKEDYNAMIC probe ()V [fr/umlv/indycov/RT#bsm, 3]
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "baz"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
    L1
    FRAME SAME
    INVOKEDYNAMIC probe ()V [fr/umlv/indycov/RT#bsm, 4]
    RETURN

A no-op, is a method handle that takes nothing and return void. This method handle can be retrieved with Methodhandles.identity(void.class).
So the bootstrap method is the following. The first line records that the basic block with number ‘index’ is visited.

  public static CallSite bsm(Lookup lookup, String name, MethodType type, Object index) {
    classValue.get(lookup.lookupClass()).cover((Integer)index);
    return new ConstantCallSite(MethodHandles.identity(void.class));
  }

The code of the prototype is freely available (as attachment of this blog)  and works like an agent.
It relies on ASM 4 (still in beta) to do the bytecode transformation.

Side note: This prototype doesn’t handle exception correctly. If an exception is thrown, it will escape from the basic block without ending it.
How to modify the prototype to take care of exception is let to interrested readers.

Running the code with one argument "foo"

  java -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic -javaagent:lib/indycov.jar -cp test-classes/ TestCoverage foo

will print

  foo
  baz
  TestCoverage: no coverage for line(s) 2 to 2
  TestCoverage: no coverage for line(s) 5 to 6

line 2 is the declaration of the class, it’s because javac adds a default constructor which is not used.
lines 5 to 6 are the ones that print "bar".

If you want to play with it don’t forget to compile your sources with the debug flag on. Otherwise, the generated bytecodes will not contain mapping information between opcodes and line numbers.

Cheers,
Rémi

Attachment Size
indycov.zip 681.84 KB

Flickr: Link Your Photos Back To Your Blog – Stuart Herbert

Feb 12, 2011

I post photos to Flickr from time to time, and then write blog articles about the photos. The blog articles get written days, weeks, sometimes months in advance of when they?re scheduled to appear on my blog ? which makes it a tad difficult to add a link from a photo to all of the blog articles that mention it.

So a couple of weekends ago I knocked up a very crude script that uses the Flickr API (via phpFlickr) to work through all of the published blog posts and make sure each of my Flickr photos has links back to each blog post that mention it. I?m posting it here in the public domain. Hopefully someone will find it a useful starting point to do something similar for their own blog.

<?php

require_once(?phpflickr-3.0/phpFlickr.php?);

$flickrApiKey = ?<your Flickr API key>?;
$flickrSecret = ?<your Flickr API secret>?;
$flickrToken ?= ?<your Flickr auth token>?;

$f = new phpFlickr($flickrApiKey, $flickrSecret);
$f->setToken($flickrToken);
$f->enableCache(?fs?, ?/tmp?, 3600);

// first step ? find the first published blog post
$url = ?http://blog.stuartherbert.com/photography/?;
$rawHtml = file_get_contents($url);
preg_match(?/<h2 id=”post-([0-9]+)”>/?, $rawHtml, $matches);

$blogPosts = array();
$flickrPhotos = array();

$latestPost = $matches[1];
$nextPost = $url . ??p=? . $latestPost;

function updatePhotos($photoIndex, $flickrPhotos,

Truncated by Planet PHP, read more at the original (another 22896 bytes)

Why PHP Namespaces Matter – Matthew Weier O’Phinney

Feb 04, 2011

You’ve heard about PHP namespaces by now. Most likely, you’ve heard about — and
likely participated in — the
bikeshedding surrounding the selection of the namespace separator.

Regardless of your thoughts on the namespace separator, or how namespaces may or
may not work in other languages, I submit to you several reasons for why I think
namespaces in PHP are a positive addition to the language.

Continue reading “Why PHP Namespaces Matter”

Ultimate MySQL variable and status reference list

Jan 08, 2011

I am constantly referring to the amazing MySQL manual, especially the option and variable reference table. But just as frequently, I want to look up blog posts on variables, or look for content in the Percona documentation or forums. So I present to you what is now my newest Firefox toolbar bookmark: an option and variable reference for all three sites in one!

abort_slave_event_count
blog
percona.com
manual

Aborted_clients
blog
percona.com
manual

Aborted_connects
blog
percona.com
manual

allow_suspicious_udfs
blog
percona.com
manual

ansi
blog
percona.com
manual

auto_increment_increment
blog
percona.com
manual

auto_increment_offset
blog
percona.com
manual

autocommit
blog
percona.com
manual

automatic_sp_privileges
blog
percona.com
manual

back_log
blog
percona.com
manual

basedir
blog
percona.com
manual

big_tables
blog
percona.com
manual

bind_address
blog
percona.com
manual

Binlog_cache_disk_use
blog
percona.com
manual

binlog_cache_size
blog
percona.com
manual

Binlog_cache_use
blog
percona.com
manual

binlog_direct_non_transactional_updates
blog
percona.com
manual

binlog_do_db
blog
percona.com
manual

binlog_format
blog
percona.com
manual

binlog_ignore_db
blog
percona.com
manual

binlog_row_event_max_size
blog
percona.com
manual

Binlog_stmt_cache_disk_use
blog
percona.com
manual

binlog_stmt_cache_size
blog
percona.com
manual

Binlog_stmt_cache_use
blog
percona.com
manual

bootstrap
blog
percona.com
manual

bulk_insert_buffer_size
blog
percona.com
manual

Bytes_received
blog
percona.com
manual

Bytes_sent
blog
percona.com
manual

character_set_client
blog
percona.com
manual

character_set_client_handshake
blog
percona.com
manual

character_set_connection
blog
percona.com
manual

character_set_database
blog
percona.com
manual

character_set_filesystem
blog
percona.com
manual

character_set_results
blog
percona.com
manual

character_set_server
blog
percona.com
manual

character_set_system
blog
percona.com
manual

character_sets_dir
blog
percona.com
manual

chroot
blog
percona.com
manual

collation_connection
blog
percona.com
manual

collation_database
blog
percona.com
manual

collation_server
blog
percona.com
manual

Com_admin_commands
blog
percona.com
manual

Com_alter_db
blog
percona.com
manual

Com_alter_db_upgrade
blog
percona.com
manual

Com_alter_event
blog
percona.com
manual

Com_alter_function
blog
percona.com
manual

Com_alter_procedure
blog
percona.com
manual

Com_alter_server
blog
percona.com
manual

Com_alter_table
blog
percona.com
manual

Com_alter_tablespace
blog
percona.com
manual

Com_analyze
blog
percona.com
manual

Com_assign_to_keycache
blog
percona.com
manual

Com_backup_table
blog
percona.com
manual

Com_begin
blog
percona.com
manual

Com_binlog
blog
percona.com
manual

Com_call_procedure
blog
percona.com
manual

Com_change_db
blog
percona.com
manual

Com_change_master
blog
percona.com
manual

Com_check
blog
percona.com
manual

Com_checksum
blog
percona.com
manual

Com_commit
blog
percona.com
manual

Com_create_db
blog
percona.com
manual

Com_create_event
blog
percona.com
manual

Com_create_function
blog
percona.com
manual

Com_create_index
blog
percona.com
manual

Com_create_procedure
blog
percona.com
manual

Com_create_server
blog
percona.com
manual

Com_create_table
blog
percona.com
manual

Com_create_trigger
blog
percona.com
manual

Com_create_udf
blog
percona.com
manual

Com_create_user
blog
percona.com
manual

Com_create_view
blog
percona.com
manual

Com_dealloc_sql
blog
percona.com
manual

Com_delete
blog
percona.com
manual

Com_delete_multi
blog
percona.com
manual

Com_do
blog
percona.com
manual

Com_drop_db
blog
percona.com
manual

Com_drop_event
blog
percona.com
manual

Com_drop_function
blog
percona.com
manual

Com_drop_index
blog
percona.com
manual

Com_drop_procedure
blog
percona.com
manual

Com_drop_server
blog
percona.com
manual

Com_drop_table
blog
percona.com
manual

Com_drop_trigger
blog
percona.com
manual

Com_drop_user
blog
percona.com
manual

Com_drop_view
blog
percona.com
manual

Com_empty_query
blog
percona.com
manual

Com_execute_sql
blog
percona.com
manual

Com_flush
blog
percona.com
manual

Com_grant
blog
percona.com
manual

Com_ha_close
blog
percona.com
manual

Com_ha_open
blog
percona.com
manual

Com_ha_read
blog
percona.com
manual

Com_help
blog
percona.com
manual

Com_insert
blog
percona.com
manual

Com_insert_select
blog
percona.com
manual

Com_install_plugin
blog
percona.com
manual

Com_kill
blog
percona.com
manual

Com_load
blog
percona.com
manual

Com_lock_tables
blog
percona.com
manual

Com_optimize
blog
percona.com
manual

Com_preload_keys
blog
percona.com
manual

Com_prepare_sql
blog
percona.com
manual

Com_purge
blog
percona.com
manual

Com_purge_before_date
blog
percona.com
manual

Com_release_savepoint
blog
percona.com
manual

Com_rename_table
blog
percona.com
manual

Com_rename_user
blog
percona.com
manual

Com_repair
blog
percona.com
manual

Com_replace
blog
percona.com
manual

Com_replace_select
blog
percona.com
manual

Com_reset
blog
percona.com
manual

Com_resignal
blog
percona.com
manual

Com_restore_table
blog
percona.com
manual

Com_revoke
blog
percona.com
manual

Com_revoke_all
blog
percona.com
manual

Com_rollback
blog
percona.com
manual

Com_rollback_to_savepoint
blog
percona.com
manual

Com_savepoint
blog
percona.com
manual

Com_select
blog
percona.com
manual

Com_set_option
blog
percona.com
manual

Com_show_authors
blog
percona.com
manual

Com_show_binlog_events
blog
percona.com
manual

Com_show_binlogs
blog
percona.com
manual

Com_show_charsets
blog
percona.com
manual

Com_show_collations
blog
percona.com
manual

Com_show_column_types
blog
percona.com
manual

Com_show_contributors
blog
percona.com
manual

Com_show_create_db
blog
percona.com
manual

Com_show_create_event
blog
percona.com
manual

Com_show_create_func
blog
percona.com
manual

Com_show_create_proc
blog
percona.com
manual

Com_show_create_table
blog
percona.com
manual

Com_show_create_trigger
blog
percona.com
manual

Com_show_databases
blog
percona.com
manual

Com_show_engine_logs
blog
percona.com
manual

Com_show_engine_mutex
blog
percona.com
manual

Com_show_engine_status
blog
percona.com
manual

Com_show_errors
blog
percona.com
manual

Com_show_events
blog
percona.com
manual

Com_show_fields
blog
percona.com
manual

Com_show_function_code
blog
percona.com
manual

Com_show_function_status
blog
percona.com
manual

Com_show_grants
blog
percona.com
manual

Com_show_innodb_status
blog
percona.com
manual

Com_show_keys
blog
percona.com
manual

Com_show_logs
blog
percona.com
manual

Com_show_master_status
blog
percona.com
manual

Com_show_new_master
blog
percona.com
manual

Com_show_open_tables
blog
percona.com
manual

Com_show_plugins
blog
percona.com
manual

Com_show_privileges
blog
percona.com
manual

Com_show_procedure_code
blog
percona.com
manual

Com_show_procedure_status
blog
percona.com
manual

Com_show_processlist
blog
percona.com
manual

Com_show_profile
blog
percona.com
manual

Com_show_profiles
blog
percona.com
manual

Com_show_relaylog_events
blog
percona.com
manual

Com_show_slave_hosts
blog
percona.com
manual

Com_show_slave_status
blog
percona.com
manual

Com_show_status
blog
percona.com
manual

Com_show_storage_engines
blog
percona.com
manual

Com_show_table_status
blog
percona.com
manual

Com_show_tables
blog
percona.com
manual

Com_show_triggers
blog
percona.com
manual

Com_show_variables
blog
percona.com
manual

Com_show_warnings
blog
percona.com
manual

Com_signal
blog
percona.com
manual

Com_slave_start
blog
percona.com
manual

Com_slave_stop
blog
percona.com
manual

Com_stmt_close
blog
percona.com
manual

Com_stmt_execute
blog
percona.com
manual

Com_stmt_fetch
blog
percona.com
manual

Com_stmt_prepare
blog
percona.com
manual

Com_stmt_reprepare
blog
percona.com
manual

Com_stmt_reset
blog
percona.com
manual

Com_stmt_send_long_data
blog
percona.com
manual

Com_truncate
blog
percona.com
manual

Com_uninstall_plugin
blog
percona.com
manual

Com_unlock_tables
blog
percona.com
manual

Com_update
blog
percona.com
manual

Com_update_multi
blog
percona.com
manual

Com_xa_commit
blog
percona.com
manual

Com_xa_end
blog
percona.com
manual

Com_xa_prepare
blog
percona.com
manual

Com_xa_recover
blog
percona.com
manual

Com_xa_rollback
blog
percona.com
manual

Com_xa_start
blog
percona.com
manual

completion_type
blog
percona.com
manual

Compression
blog
percona.com
manual

concurrent_insert
blog
percona.com
manual

connect_timeout
blog
percona.com
manual

Connections
blog
percona.com
manual

console
blog
percona.com
manual

core_file
blog
percona.com
manual

Created_tmp_disk_tables
blog
percona.com
manual

Created_tmp_files
blog
percona.com
manual

Created_tmp_tables
blog
percona.com
manual

datadir
blog
percona.com
manual

date_format
blog
percona.com
manual

datetime_format
blog
percona.com
manual

debug
blog
percona.com
manual

debug_sync
blog
percona.com
manual

debug_sync_timeout
blog
percona.com
manual

default_storage_engine
blog
percona.com
manual

default_time_zone
blog
percona.com
manual

default_week_format
blog
percona.com
manual

defaults_extra_file
blog
percona.com
manual

defaults_file
blog
percona.com
manual

defaults_group_suffix
blog
percona.com
manual

delay_key_write
blog
percona.com
manual

Delayed_errors
blog
percona.com
manual

delayed_insert_limit
blog
percona.com
manual

Delayed_insert_threads
blog
percona.com
manual

delayed_insert_timeout
blog
percona.com
manual

delayed_queue_size
blog
percona.com
manual

Delayed_writes
blog
percona.com
manual

des_key_file
blog
percona.com
manual

disconnect_slave_event_count
blog
percona.com
manual

div_precision_increment
blog
percona.com
manual

enable_locking
blog
percona.com
manual

enable_named_pipe
blog
percona.com
manual

enable_pstack
blog
percona.com
manual

engine_condition_pushdown
blog
percona.com
manual

error_count
blog
percona.com
manual

event_scheduler
blog
percona.com
manual

exit_info
blog
percona.com
manual

expire_logs_days
blog
percona.com
manual

external_locking
blog
percona.com
manual

external_user
blog
percona.com
manual

federated
blog
percona.com
manual

flush
blog
percona.com
manual

Flush_commands
blog
percona.com
manual

flush_time
blog
percona.com
manual

foreign_key_checks
blog
percona.com
manual

ft_boolean_syntax
blog
percona.com
manual

ft_max_word_len
blog
percona.com
manual

ft_min_word_len
blog
percona.com
manual

ft_query_expansion_limit
blog
percona.com
manual

ft_stopword_file
blog
percona.com
manual

gdb
blog
percona.com
manual

general_log
blog
percona.com
manual

general_log_file
blog
percona.com
manual

group_concat_max_len
blog
percona.com
manual

Handler_commit
blog
percona.com
manual

Handler_delete
blog
percona.com
manual

Handler_prepare
blog
percona.com
manual

Handler_read_first
blog
percona.com
manual

Handler_read_key
blog
percona.com
manual

Handler_read_last
blog
percona.com
manual

Handler_read_next
blog
percona.com
manual

Handler_read_prev
blog
percona.com
manual

Handler_read_rnd
blog
percona.com
manual

Handler_read_rnd_next
blog
percona.com
manual

Handler_rollback
blog
percona.com
manual

Handler_savepoint
blog
percona.com
manual

Handler_savepoint_rollback
blog
percona.com
manual

Handler_update
blog
percona.com
manual

Handler_write
blog
percona.com
manual

have_compress
blog
percona.com
manual

have_crypt
blog
percona.com
manual

have_csv
blog
percona.com
manual

have_dynamic_loading
blog
percona.com
manual

have_geometry
blog
percona.com
manual

have_innodb
blog
percona.com
manual

have_openssl
blog
percona.com
manual

have_partitioning
blog
percona.com
manual

have_profiling
blog
percona.com
manual

have_query_cache
blog
percona.com
manual

have_rtree_keys
blog
percona.com
manual

have_ssl
blog
percona.com
manual

have_symlink
blog
percona.com
manual

help
blog
percona.com
manual

hostname
blog
percona.com
manual

identity
blog
percona.com
manual

ignore_builtin_innodb
blog
percona.com
manual

init_connect
blog
percona.com
manual

init_file
blog
percona.com
manual

init_slave
blog
percona.com
manual

innodb
blog
percona.com
manual

innodb_adaptive_flushing
blog
percona.com
manual

innodb_adaptive_hash_index
blog
percona.com
manual

innodb_additional_mem_pool_size
blog
percona.com
manual

innodb_autoextend_increment
blog
percona.com
manual

innodb_autoinc_lock_mode
blog
percona.com
manual

innodb_buffer_pool_instances
blog
percona.com
manual

Innodb_buffer_pool_pages_data
blog
percona.com
manual

Innodb_buffer_pool_pages_dirty
blog
percona.com
manual

Innodb_buffer_pool_pages_flushed
blog
percona.com
manual

Innodb_buffer_pool_pages_free
blog
percona.com
manual

Innodb_buffer_pool_pages_latched
blog
percona.com
manual

Innodb_buffer_pool_pages_misc
blog
percona.com
manual

Innodb_buffer_pool_pages_total
blog
percona.com
manual

Innodb_buffer_pool_read_ahead
blog
percona.com
manual

Innodb_buffer_pool_read_ahead_evicted
blog
percona.com
manual

Innodb_buffer_pool_read_requests
blog
percona.com
manual

Innodb_buffer_pool_reads
blog
percona.com
manual

innodb_buffer_pool_size
blog
percona.com
manual

Innodb_buffer_pool_wait_free
blog
percona.com
manual

Innodb_buffer_pool_write_requests
blog
percona.com
manual

innodb_change_buffering
blog
percona.com
manual

innodb_checksums
blog
percona.com
manual

innodb_commit_concurrency
blog
percona.com
manual

innodb_concurrency_tickets
blog
percona.com
manual

innodb_data_file_path
blog
percona.com
manual

Innodb_data_fsyncs
blog
percona.com
manual

innodb_data_home_dir
blog
percona.com
manual

Innodb_data_pending_fsyncs
blog
percona.com
manual

Innodb_data_pending_reads
blog
percona.com
manual

Innodb_data_pending_writes
blog
percona.com
manual

Innodb_data_read
blog
percona.com
manual

Innodb_data_reads
blog
percona.com
manual

Innodb_data_writes
blog
percona.com
manual

Innodb_data_written
blog
percona.com
manual

Innodb_dblwr_pages_written
blog
percona.com
manual

Innodb_dblwr_writes
blog
percona.com
manual

innodb_doublewrite
blog
percona.com
manual

innodb_fast_shutdown
blog
percona.com
manual

innodb_file_format
blog
percona.com
manual

innodb_file_format_check
blog
percona.com
manual

innodb_file_format_max
blog
percona.com
manual

innodb_file_per_table
blog
percona.com
manual

innodb_flush_log_at_trx_commit
blog
percona.com
manual

innodb_flush_method
blog
percona.com
manual

innodb_force_recovery
blog
percona.com
manual

Innodb_have_atomic_builtins
blog
percona.com
manual

innodb_io_capacity
blog
percona.com
manual

innodb_lock_wait_timeout
blog
percona.com
manual

innodb_locks_unsafe_for_binlog
blog
percona.com
manual

innodb_log_buffer_size
blog
percona.com
manual

innodb_log_file_size
blog
percona.com
manual

innodb_log_files_in_group
blog
percona.com
manual

innodb_log_group_home_dir
blog
percona.com
manual

Innodb_log_waits
blog
percona.com
manual

Innodb_log_write_requests
blog
percona.com
manual

Innodb_log_writes
blog
percona.com
manual

innodb_max_dirty_pages_pct
blog
percona.com
manual

innodb_max_purge_lag
blog
percona.com
manual

innodb_mirrored_log_groups
blog
percona.com
manual

innodb_old_blocks_pct
blog
percona.com
manual

innodb_old_blocks_time
blog
percona.com
manual

innodb_open_files
blog
percona.com
manual

Innodb_os_log_fsyncs
blog
percona.com
manual

Innodb_os_log_pending_fsyncs
blog
percona.com
manual

Innodb_os_log_pending_writes
blog
percona.com
manual

Innodb_os_log_written
blog
percona.com
manual

Innodb_page_size
blog
percona.com
manual

Innodb_pages_created
blog
percona.com
manual

Innodb_pages_read
blog
percona.com
manual

Innodb_pages_written
blog
percona.com
manual

innodb_purge_batch_size
blog
percona.com
manual

innodb_purge_threads
blog
percona.com
manual

innodb_read_ahead_threshold
blog
percona.com
manual

innodb_read_io_threads
blog
percona.com
manual

innodb_replication_delay
blog
percona.com
manual

innodb_rollback_on_timeout
blog
percona.com
manual

Innodb_row_lock_current_waits
blog
percona.com
manual

Innodb_row_lock_time
blog
percona.com
manual

Innodb_row_lock_time_avg
blog
percona.com
manual

Innodb_row_lock_time_max
blog
percona.com
manual

Innodb_row_lock_waits
blog
percona.com
manual

Innodb_rows_deleted
blog
percona.com
manual

Innodb_rows_inserted
blog
percona.com
manual

Innodb_rows_read
blog
percona.com
manual

Innodb_rows_updated
blog
percona.com
manual

innodb_spin_wait_delay
blog
percona.com
manual

innodb_stats_on_metadata
blog
percona.com
manual

innodb_stats_sample_pages
blog
percona.com
manual

innodb_status_file
blog
percona.com
manual

innodb_strict_mode
blog
percona.com
manual

innodb_support_xa
blog
percona.com
manual

innodb_sync_spin_loops
blog
percona.com
manual

innodb_table_locks
blog
percona.com
manual

innodb_thread_concurrency
blog
percona.com
manual

innodb_thread_sleep_delay
blog
percona.com
manual

Innodb_truncated_status_writes
blog
percona.com
manual

innodb_use_native_aio
blog
percona.com
manual

innodb_use_sys_malloc
blog
percona.com
manual

innodb_version
blog
percona.com
manual

innodb_write_io_threads
blog
percona.com
manual

insert_id
blog
percona.com
manual

interactive_timeout
blog
percona.com
manual

join_buffer_size
blog
percona.com
manual

keep_files_on_create
blog
percona.com
manual

Key_blocks_not_flushed
blog
percona.com
manual

Key_blocks_unused
blog
percona.com
manual

Key_blocks_used
blog
percona.com
manual

key_buffer_size
blog
percona.com
manual

key_cache_age_threshold
blog
percona.com
manual

key_cache_block_size
blog
percona.com
manual

key_cache_division_limit
blog
percona.com
manual

Key_read_requests
blog
percona.com
manual

Key_reads
blog
percona.com
manual

Key_write_requests
blog
percona.com
manual

Key_writes
blog
percona.com
manual

language
blog
percona.com
manual

large_files_support
blog
percona.com
manual

large_page_size
blog
percona.com
manual

large_pages
blog
percona.com
manual

last_insert_id
blog
percona.com
manual

Last_query_cost
blog
percona.com
manual

lc_messages
blog
percona.com
manual

lc_messages_dir
blog
percona.com
manual

lc_time_names
blog
percona.com
manual

license
blog
percona.com
manual

local_infile
blog
percona.com
manual

local_infile
blog
percona.com
manual

lock_wait_timeout
blog
percona.com
manual

locked_in_memory
blog
percona.com
manual

log
blog
percona.com
manual

log_bin
blog
percona.com
manual

log_bin
blog
percona.com
manual

log_bin_index
blog
percona.com
manual

log_bin_trust_function_creators
blog
percona.com
manual

log_error
blog
percona.com
manual

log_isam
blog
percona.com
manual

log_output
blog
percona.com
manual

log_queries_not_using_indexes
blog
percona.com
manual

log_short_format
blog
percona.com
manual

log_slave_updates
blog
percona.com
manual

log_slow_admin_statements
blog
percona.com
manual

log_slow_queries
blog
percona.com
manual

log_slow_slave_statements
blog
percona.com
manual

log_tc
blog
percona.com
manual

log_tc_size
blog
percona.com
manual

log_warnings
blog
percona.com
manual

long_query_time
blog
percona.com
manual

low_priority_updates
blog
percona.com
manual

lower_case_file_system
blog
percona.com
manual

lower_case_table_names
blog
percona.com
manual

master_bind
blog
percona.com
manual

master_connect_retry
blog
percona.com
manual

master_host
blog
percona.com
manual

master_info_file
blog
percona.com
manual

master_password
blog
percona.com
manual

master_port
blog
percona.com
manual

master_retry_count
blog
percona.com
manual

master_ssl
blog
percona.com
manual

master_ssl_ca
blog
percona.com
manual

master_ssl_capath
blog
percona.com
manual

master_ssl_cert
blog
percona.com
manual

master_ssl_cipher
blog
percona.com
manual

master_ssl_key
blog
percona.com
manual

master_user
blog
percona.com
manual

max_allowed_packet
blog
percona.com
manual

max_binlog_cache_size
blog
percona.com
manual

max_binlog_dump_events
blog
percona.com
manual

max_binlog_size
blog
percona.com
manual

max_binlog_stmt_cache_size
blog
percona.com
manual

max_connect_errors
blog
percona.com
manual

max_connections
blog
percona.com
manual

max_delayed_threads
blog
percona.com
manual

max_error_count
blog
percona.com
manual

max_heap_table_size
blog
percona.com
manual

max_insert_delayed_threads
blog
percona.com
manual

max_join_size
blog
percona.com
manual

max_length_for_sort_data
blog
percona.com
manual

max_prepared_stmt_count
blog
percona.com
manual

max_relay_log_size
blog
percona.com
manual

max_seeks_for_key
blog
percona.com
manual

max_sort_length
blog
percona.com
manual

max_sp_recursion_depth
blog
percona.com
manual

max_tmp_tables
blog
percona.com
manual

Max_used_connections
blog
percona.com
manual

max_user_connections
blog
percona.com
manual

max_write_lock_count
blog
percona.com
manual

memlock
blog
percona.com
manual

min_examined_row_limit
blog
percona.com
manual

myisam_block_size
blog
percona.com
manual

myisam_data_pointer_size
blog
percona.com
manual

myisam_max_sort_file_size
blog
percona.com
manual

myisam_mmap_size
blog
percona.com
manual

myisam_recover
blog
percona.com
manual

myisam_recover_options
blog
percona.com
manual

myisam_recover_options
blog
percona.com
manual

myisam_repair_threads
blog
percona.com
manual

myisam_sort_buffer_size
blog
percona.com
manual

myisam_stats_method
blog
percona.com
manual

myisam_use_mmap
blog
percona.com
manual

named_pipe
blog
percona.com
manual

net_buffer_length
blog
percona.com
manual

net_read_timeout
blog
percona.com
manual

net_retry_count
blog
percona.com
manual

net_write_timeout
blog
percona.com
manual

new
blog
percona.com
manual

no_defaults
blog
percona.com
manual

Not_flushed_delayed_rows
blog
percona.com
manual

old
blog
percona.com
manual

old_alter_table
blog
percona.com
manual

old_passwords
blog
percona.com
manual

old_style_user_limits
blog
percona.com
manual

one_thread
blog
percona.com
manual

Open_files
blog
percona.com
manual

open_files_limit
blog
percona.com
manual

Open_streams
blog
percona.com
manual

Open_table_definitions
blog
percona.com
manual

Open_tables
blog
percona.com
manual

Opened_files
blog
percona.com
manual

Opened_table_definitions
blog
percona.com
manual

Opened_tables
blog
percona.com
manual

optimizer_prune_level
blog
percona.com
manual

optimizer_search_depth
blog
percona.com
manual

optimizer_switch
blog
percona.com
manual

partition
blog
percona.com
manual

performance_schema
blog
percona.com
manual

Performance_schema_cond_classes_lost
blog
percona.com
manual

Performance_schema_cond_instances_lost
blog
percona.com
manual

performance_schema_events_waits_history_long_size
blog
percona.com
manual

performance_schema_events_waits_history_size
blog
percona.com
manual

Performance_schema_file_classes_lost
blog
percona.com
manual

Performance_schema_file_handles_lost
blog
percona.com
manual

Performance_schema_file_instances_lost
blog
percona.com
manual

Performance_schema_locker_lost
blog
percona.com
manual

performance_schema_max_cond_classes
blog
percona.com
manual

performance_schema_max_cond_instances
blog
percona.com
manual

performance_schema_max_file_classes
blog
percona.com
manual

performance_schema_max_file_handles
blog
percona.com
manual

performance_schema_max_file_instances
blog
percona.com
manual

performance_schema_max_mutex_classes
blog
percona.com
manual

performance_schema_max_mutex_instances
blog
percona.com
manual

performance_schema_max_rwlock_classes
blog
percona.com
manual

performance_schema_max_rwlock_instances
blog
percona.com
manual

performance_schema_max_table_handles
blog
percona.com
manual

performance_schema_max_table_instances
blog
percona.com
manual

performance_schema_max_thread_classes
blog
percona.com
manual

performance_schema_max_thread_instances
blog
percona.com
manual

Performance_schema_mutex_classes_lost
blog
percona.com
manual

Performance_schema_mutex_instances_lost
blog
percona.com
manual

Performance_schema_rwlock_classes_lost
blog
percona.com
manual

Performance_schema_rwlock_instances_lost
blog
percona.com
manual

Performance_schema_table_handles_lost
blog
percona.com
manual

Performance_schema_table_instances_lost
blog
percona.com
manual

Performance_schema_thread_classes_lost
blog
percona.com
manual

Performance_schema_thread_instances_lost
blog
percona.com
manual

pid_file
blog
percona.com
manual

plugin
blog
percona.com
manual

plugin_dir
blog
percona.com
manual

plugin_load
blog
percona.com
manual

port
blog
percona.com
manual

port_open_timeout
blog
percona.com
manual

preload_buffer_size
blog
percona.com
manual

Prepared_stmt_count
blog
percona.com
manual

print_defaults
blog
percona.com
manual

profiling
blog
percona.com
manual

profiling_history_size
blog
percona.com
manual

protocol_version
blog
percona.com
manual

proxy_user
blog
percona.com
manual

pseudo_thread_id
blog
percona.com
manual

Qcache_free_blocks
blog
percona.com
manual

Qcache_free_memory
blog
percona.com
manual

Qcache_hits
blog
percona.com
manual

Qcache_inserts
blog
percona.com
manual

Qcache_lowmem_prunes
blog
percona.com
manual

Qcache_not_cached
blog
percona.com
manual

Qcache_queries_in_cache
blog
percona.com
manual

Qcache_total_blocks
blog
percona.com
manual

Queries
blog
percona.com
manual

query_alloc_block_size
blog
percona.com
manual

query_cache_limit
blog
percona.com
manual

query_cache_min_res_unit
blog
percona.com
manual

query_cache_size
blog
percona.com
manual

query_cache_type
blog
percona.com
manual

query_cache_wlock_invalidate
blog
percona.com
manual

query_prealloc_size
blog
percona.com
manual

Questions
blog
percona.com
manual

rand_seed1
blog
percona.com
manual

rand_seed2
blog
percona.com
manual

range_alloc_block_size
blog
percona.com
manual

read_buffer_size
blog
percona.com
manual

read_only
blog
percona.com
manual

read_rnd_buffer_size
blog
percona.com
manual

relay_log
blog
percona.com
manual

relay_log_index
blog
percona.com
manual

relay_log_info_file
blog
percona.com
manual

relay_log_purge
blog
percona.com
manual

relay_log_recovery
blog
percona.com
manual

relay_log_space_limit
blog
percona.com
manual

replicate_do_db
blog
percona.com
manual

replicate_do_table
blog
percona.com
manual

replicate_ignore_db
blog
percona.com
manual

replicate_ignore_table
blog
percona.com
manual

replicate_rewrite_db
blog
percona.com
manual

replicate_same_server_id
blog
percona.com
manual

replicate_wild_do_table
blog
percona.com
manual

replicate_wild_ignore_table
blog
percona.com
manual

report_host
blog
percona.com
manual

report_password
blog
percona.com
manual

report_port
blog
percona.com
manual

report_user
blog
percona.com
manual

rpl_recovery_rank
blog
percona.com
manual

Rpl_semi_sync_master_clients
blog
percona.com
manual

rpl_semi_sync_master_enabled
blog
percona.com
manual

Rpl_semi_sync_master_net_avg_wait_time
blog
percona.com
manual

Rpl_semi_sync_master_net_wait_time
blog
percona.com
manual

Rpl_semi_sync_master_net_waits
blog
percona.com
manual

Rpl_semi_sync_master_no_times
blog
percona.com
manual

Rpl_semi_sync_master_no_tx
blog
percona.com
manual

Rpl_semi_sync_master_status
blog
percona.com
manual

Rpl_semi_sync_master_timefunc_failures
blog
percona.com
manual

rpl_semi_sync_master_timeout
blog
percona.com
manual

rpl_semi_sync_master_trace_level
blog
percona.com
manual

Rpl_semi_sync_master_tx_avg_wait_time
blog
percona.com
manual

Rpl_semi_sync_master_tx_wait_time
blog
percona.com
manual

Rpl_semi_sync_master_tx_waits
blog
percona.com
manual

rpl_semi_sync_master_wait_no_slave
blog
percona.com
manual

Rpl_semi_sync_master_wait_pos_backtraverse
blog
percona.com
manual

Rpl_semi_sync_master_wait_sessions
blog
percona.com
manual

Rpl_semi_sync_master_yes_tx
blog
percona.com
manual

rpl_semi_sync_slave_enabled
blog
percona.com
manual

Rpl_semi_sync_slave_status
blog
percona.com
manual

rpl_semi_sync_slave_trace_level
blog
percona.com
manual

Rpl_status
blog
percona.com
manual

safe_mode
blog
percona.com
manual

safe_show_database
blog
percona.com
manual

safe_user_create
blog
percona.com
manual

secure_auth
blog
percona.com
manual

secure_file_priv
blog
percona.com
manual

Select_full_join
blog
percona.com
manual

Select_full_range_join
blog
percona.com
manual

Select_range
blog
percona.com
manual

Select_range_check
blog
percona.com
manual

Select_scan
blog
percona.com
manual

server_id
blog
percona.com
manual

shared_memory
blog
percona.com
manual

shared_memory_base_name
blog
percona.com
manual

show_slave_auth_info
blog
percona.com
manual

skip_character_set_client_handshake
blog
percona.com
manual

skip_concurrent_insert
blog
percona.com
manual

skip_event_scheduler
blog
percona.com
manual

skip_external_locking
blog
percona.com
manual

skip_grant_tables
blog
percona.com
manual

skip_host_cache
blog
percona.com
manual

skip_locking
blog
percona.com
manual

skip_log_warnings
blog
percona.com
manual

skip_name_resolve
blog
percona.com
manual

skip_networking
blog
percona.com
manual

skip_partition
blog
percona.com
manual

skip_safemalloc
blog
percona.com
manual

skip_show_database
blog
percona.com
manual

skip_slave_start
blog
percona.com
manual

skip_ssl
blog
percona.com
manual

skip_stack_trace
blog
percona.com
manual

skip_symbolic_links
blog
percona.com
manual

skip_thread_priority
blog
percona.com
manual

slave_compressed_protocol
blog
percona.com
manual

slave_exec_mode
blog
percona.com
manual

Slave_heartbeat_period
blog
percona.com
manual

slave_load_tmpdir
blog
percona.com
manual

slave_net_timeout
blog
percona.com
manual

Slave_open_temp_tables
blog
percona.com
manual

Slave_received_heartbeats
blog
percona.com
manual

Slave_retried_transactions
blog
percona.com
manual

Slave_running
blog
percona.com
manual

slave_skip_errors
blog
percona.com
manual

slave_transaction_retries
blog
percona.com
manual

slave_type_conversions
blog
percona.com
manual

Slow_launch_threads
blog
percona.com
manual

slow_launch_time
blog
percona.com
manual

Slow_queries
blog
percona.com
manual

slow_query_log
blog
percona.com
manual

slow_query_log_file
blog
percona.com
manual

socket
blog
percona.com
manual

sort_buffer_size
blog
percona.com
manual

Sort_merge_passes
blog
percona.com
manual

Sort_range
blog
percona.com
manual

Sort_rows
blog
percona.com
manual

Sort_scan
blog
percona.com
manual

sporadic_binlog_dump_fail
blog
percona.com
manual

sql_auto_is_null
blog
percona.com
manual

sql_big_selects
blog
percona.com
manual

sql_big_tables
blog
percona.com
manual

sql_buffer_result
blog
percona.com
manual

sql_log_bin
blog
percona.com
manual

sql_log_off
blog
percona.com
manual

sql_log_update
blog
percona.com
manual

sql_low_priority_updates
blog
percona.com
manual

sql_max_join_size
blog
percona.com
manual

sql_mode
blog
percona.com
manual

sql_notes
blog
percona.com
manual

sql_quote_show_create
blog
percona.com
manual

sql_safe_updates
blog
percona.com
manual

sql_select_limit
blog
percona.com
manual

sql_slave_skip_counter
blog
percona.com
manual

sql_warnings
blog
percona.com
manual

ssl
blog
percona.com
manual

Ssl_accept_renegotiates
blog
percona.com
manual

Ssl_accepts
blog
percona.com
manual

ssl_ca
blog
percona.com
manual

Ssl_callback_cache_hits
blog
percona.com
manual

ssl_capath
blog
percona.com
manual

ssl_cert
blog
percona.com
manual

ssl_cipher
blog
percona.com
manual

Ssl_cipher
blog
percona.com
manual

Ssl_cipher_list
blog
percona.com
manual

Ssl_client_connects
blog
percona.com
manual

Ssl_connect_renegotiates
blog
percona.com
manual

Ssl_ctx_verify_depth
blog
percona.com
manual

Ssl_ctx_verify_mode
blog
percona.com
manual

Ssl_default_timeout
blog
percona.com
manual

Ssl_finished_accepts
blog
percona.com
manual

Ssl_finished_connects
blog
percona.com
manual

ssl_key
blog
percona.com
manual

Ssl_session_cache_hits
blog
percona.com
manual

Ssl_session_cache_misses
blog
percona.com
manual

Ssl_session_cache_mode
blog
percona.com
manual

Ssl_session_cache_overflows
blog
percona.com
manual

Ssl_session_cache_size
blog
percona.com
manual

Ssl_session_cache_timeouts
blog
percona.com
manual

Ssl_sessions_reused
blog
percona.com
manual

Ssl_used_session_cache_entries
blog
percona.com
manual

Ssl_verify_depth
blog
percona.com
manual

Ssl_verify_mode
blog
percona.com
manual

ssl_verify_server_cert
blog
percona.com
manual

Ssl_version
blog
percona.com
manual

standalone
blog
percona.com
manual

storage_engine
blog
percona.com
manual

symbolic_links
blog
percona.com
manual

sync_binlog
blog
percona.com
manual

sync_frm
blog
percona.com
manual

sync_master_info
blog
percona.com
manual

sync_relay_log
blog
percona.com
manual

sync_relay_log_info
blog
percona.com
manual

sysdate_is_now
blog
percona.com
manual

system_time_zone
blog
percona.com
manual

table_definition_cache
blog
percona.com
manual

table_lock_wait_timeout
blog
percona.com
manual

Table_locks_immediate
blog
percona.com
manual

Table_locks_waited
blog
percona.com
manual

table_open_cache
blog
percona.com
manual

table_type
blog
percona.com
manual

tc_heuristic_recover
blog
percona.com
manual

Tc_log_max_pages_used
blog
percona.com
manual

Tc_log_page_size
blog
percona.com
manual

Tc_log_page_waits
blog
percona.com
manual

temp_pool
blog
percona.com
manual

thread_cache_size
blog
percona.com
manual

thread_concurrency
blog
percona.com
manual

thread_handling
blog
percona.com
manual

thread_stack
blog
percona.com
manual

Threads_cached
blog
percona.com
manual

Threads_connected
blog
percona.com
manual

Threads_created
blog
percona.com
manual

Threads_running
blog
percona.com
manual

time_format
blog
percona.com
manual

time_zone
blog
percona.com
manual

timed_mutexes
blog
percona.com
manual

timestamp
blog
percona.com
manual

tmp_table_size
blog
percona.com
manual

tmpdir
blog
percona.com
manual

transaction_alloc_block_size
blog
percona.com
manual

transaction_isolation
blog
percona.com
manual

transaction_prealloc_size
blog
percona.com
manual

tx_isolation
blog
percona.com
manual

unique_checks
blog
percona.com
manual

updatable_views_with_limit
blog
percona.com
manual

Uptime
blog
percona.com
manual

Uptime_since_flush_status
blog
percona.com
manual

user
blog
percona.com
manual

verbose
blog
percona.com
manual

version
blog
percona.com
manual

version_comment
blog
percona.com
manual

version_compile_machine
blog
percona.com
manual

version_compile_os
blog
percona.com
manual

wait_timeout
blog
percona.com
manual

warning_count
blog
percona.com
manual

Entry posted by Baron Schwartz |
No comment
Add to: | | | |

Calling invokedynamic in Java

Jan 07, 2011

DynamicIndy

There is no way to invoke invokedynamic using the Java language. So testing invokedynamic is not that obvious if you don’t have your own dynamic language.
I’ve developed a small class DynamicIndy that uses ASM 4.0 (not an official release) to generate a static method that calls invokedynamic. These static method is after converted to a MethodHandle that can be called in Java
The code is available at the bottom of this post

How to use it ?

DynamicIndy defines a method named (judiciously :) invokedynamic that takes a name and a MethodType, a way to specify a bootstrap method (a triple class, method name, method type ) and some optional arguments for the bootstrap method.
The following code shows how to create a BigDecimal constant using invokedynamic.

This code shows how to use it:

 public class DynamicIndyTest {
  public static CallSite bsm(Lookup lookup, String name, MethodType methodType, Object arg) {
    System.out.println("construct the BigDecimal constant "+arg);
    return new ConstantCallSite(
        MethodHandles.constant(BigDecimal.class, new BigDecimal(arg.toString())));
  }

  public static void main(String[] args) throws Throwable {
    DynamicIndy dynamicIndy = new DynamicIndy();
    MethodHandle mh = dynamicIndy.invokeDynamic("_", MethodType.methodType(BigDecimal.class),
        DynamicIndyTest.class, "bsm", MethodType.methodType(CallSite.class, Lookup.class, String.class, MethodType.class, Object.class),
        "1234567890.1234567890"
        );
    System.out.println((BigDecimal)mh.invokeExact());
    System.out.println((BigDecimal)mh.invokeExact());
  }
}

If you run this code

java -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic
  -cp .:asm-all-4.0-beta1.jar DynamicIndyTest

it will print

construct the BigDecimal constant 1234567890.1234567890
1234567890.1234567890
1234567890.1234567890

As you see the bootstrap method is called once and the constant reused.

cheers,
Rémi

Attachment Size
dynamic-indy.zip 289.49 KB

New Leonardo Sketch Release: Ruby Red Remixed

Jan 02, 2011

Josh Marinacci has announced that a new version of Leonardo Sketch is now available: Ruby Red Remixed. Leonardo is:

an open source vector drawing program named after the 15th century painter, but aimed for the 21st century user. It focuses on common tasks like mockups, prototyping, quick vector sketches, and presentations with a clean and consistent user interface. Leo is designed to be augmented by internet webservices and plugins created in several scripting languages.

Ruby Red Remixed is an interim release along the path to the next major Leonardo release, Glowing Green. The release was pushed out to make the recent progress on the Leonardo platform available to the community, within the context of a formal, stable version. Ruby Red Revisited includes “tons of bug fixes,” as well as many significant new features.

Key new features include:

  • Infinite Canvas: The canvas will automatically grow as you add new objects to your drawing, even if they are beyond the edges of the document. Never run out of space again.
  • Draggable guidelines: create guidelines by dragging them out from the ruler. Objects will snap to them automatically.
  • Flickr upload support: Now you can upload your creations directly to Flickr as well as Twitter.
  • Improved SVG Import: Lots of Illustrator symbols can be imported now by exporting them as SVG from Illustrator.
  • New Rectangle UI: set rectangle corner radius and gradients directly with handles instead of with a palette. Much easier to use.
  • Improved translations, including Japanese. Edit or create new translations easily using the debug menu in the preferences.

See Ruby Red Remixed for more details on the latest release, and visit the Leonardo Sketch home page for additional information about Leonardo, the underpinning Amino library, and more.


Java Today

JUG Chennai (India) celebrated the New Year with Java User Group – Chennai JUGChennai Unconference meet, 1st January 2011 at Adams Studio India:

Agenda: JVM Langauges ? Rajmahendra. * 10:10AM Program started with Devraj talk on Flex and Java; * 10:30AM Talk on JVM Langauges. Why JVM Languages, Idea behind, Pros and Cons,Different types of Languages and introduction Gorrvy, Scala, JRuby, Fantom. JavaFX Script; * 11:30AM Product of JVM Languages Grails,Gradle, Lift, Tales; * 12:30PM Grails and Grails Demo…

Alexis Moussine-Pouchkine reviews GlassFish in 2010 – What a year!

A lot has happened over the past 12 months! For the GlassFish team as for many people that came from Sun, it’s been a challenging, yet exciting year. It all started in January with…

Hildeberto Mendon?a has a 2011 New Year’s Resolution – CEJUG: Commitment with My Homeland -

I will start this post making a promise for 2011: I will write at least a post per week in this blog. Last year I could not keep that promise because it was one of the toughest years for me. 2010 was the year of conclusions and analysis of future steps. I was in the last year of the PhD and I spent almost the whole year thinking about what to do next…

Jean-Fran?ois Bonbhel announces JCertif 2011 the biggest Java Community Event in Central Africa ! Save the dates : 27-28 August 2011 -

Hi All, I’ll like to let you know the dates of JCertif 2011 the biggest Java Community Event in Africa. About 800+ attendees from many countries.
We will be happy to have you as Speaker on Developer Tools, Java, Open Source, Mobile Apps…or Business solutions. tools. Still hesitating to join JCertif 2011 ? See The past event : JCertif 2010 and this blog post


Spotlights

Our latest java.net href="http://www.java.net/archive/spotlight">Spotlight is Micha Kops’ latest article, Enterprise Java Bean / EJB 3.1 Testing using Maven and embedded Glassfish:

Are you playing around with the shiny new 3.1 EJBs? Using Maven for your Java projects? Need an easy way to write and execute tests for your EJBs that depends on an Java Application Server? No problem using Maven Archetypes, the Maven EJB Plugin and the GlassFish embedded Application Container…

We’re also featuring JUG Chennai’s online newspaper, The JavaUserGroupChennai Daily. Recent headlines included New Year’s Eve wishes, a 2011 Android wish list, an article on SOA and MDM, and “Java EE Productivity Report 2011.”


Poll

Our current java.net poll asks Are you more optimistic today about Java’s future than you were a year ago? Voting will be open until Monday.


Subscriptions and Archives: You can subscribe to this blog using the java.net Editor’s Blog Feed. You can also subscribe to the Java Today RSS feed and the java.net blogs feed. You can find historical archives of what has appeared the front page of java.net in the java.net home page archive.

Kevin Farnham

Twitter: @kevin_farnham

Kai Toedter: Dynamic modular Web Applications with Vaadin and OSGi

Jan 02, 2011

I am a big fan of both OSGi and GWT (Google Web Toolkit). Unfortunately these two technologies don?t fit together very well. When you want to run OSGi on the server, RAP (Rich Ajax Platform) is one proven approach to go. While I like RAP a lot, you have to have quite a lot of Eclipse RCP know how for using it. Another alternative, if your want to run OSGi on the server and provide a modular, dynamic UI is Vaadin. Btw, Vaadin is the Finnish word for female reindeer. Vaadin is a server side RIA framework that uses GWT as rendering engine. In the last couple of days a played a bit around with Vaadin and I have to admit, I like it a lot. So, I wrote a little dynamic OSGi Vaadin demo (Download link and instructions are below). My goals for the demo were:

  • Provide Bundles that contribute directly to the web application?s UI
  • Just starting and stopping bundles should contribute/remove UI elements and functionality
  • I wanted to implement something similar to my dynamic Swing OSGi demo

Before I started with Vaadin, I found a few interesting reads and code sample regarding OSGi and Vaadin:

But back to the demo, here is a screen shot running the application in Firefox:

The idea is to support two kinds of UI contributions: views and actions. The views are inserted in a tab folder, the actions appear in the toolbar and the Action menu. I implemented a little OSGi agent as a view (Bundle View). This view shows a selection of bundles currently available. By checking/unchecking a bundle, it will be activated/stopped on the server side. If you press ?Deselect All?, all bundles go to resolved state and all the UI contributions disappear immediately:

Of course you could start and stop bundles from the OSGi console directly, then you would have to refresh the browser to get the changes displayed. To get the demo running on your local machine, follow these steps:

  • Make sure you have an Eclipse IDE installed
  • Download the demo sources and target platform osgi-vaadin-demo.zip (6.8 MB)
  • Import all projects from the zip file into Eclipse
  • Open the project ?com.siemens.ct.osgi.vaadin.target?
  • Double-click vaadin.target (That opens the target platform definition in an editor)
  • Click on ?Set as Target Platform? in the right top corner of the editor
  • Now everything should compile
  • Start the Run Configuration ?OSGi Vaadin Demo?
  • Open the following URL in your favorite browser ?http://localhost/com.siemens.ct.osgi.vaadin.pm.main?
  • If everything went well, you see the demo in your browser
  • Play around with it, activate/stop bundles and watch the console log

In the next weeks I plan to go a little bit more into details of the demo, how OSGi declarative services are used, how to contribute to Vaadin Themes, etc.

Stay tuned and have fun!

Kai

Follow me on Twitter

flattr this!

Jamis Buck: Maze Generation: Eller’s Algorithm

Dec 30, 2010

Last time I talked about the recursive backtracker algorithm for maze generation. That?s probably always going to be my favorite algorithm for generating mazes, for a variety of reasons, but that?s not going to stop me from looking at others.

For one thing, there are some pretty crazy algorithms out there for generating mazes.

Eller?s algorithm is one of the craziest. It?s also one of the fastest. And it?s the only one I know that let?s you generate mazes of an infinite size. In linear time.

Yeah, it?s that crazy.

It does this by building the maze one row at a time, using sets to keep track of which columns are ultimately connected. But it never needs to look at more than a single row, and when it finishes, it always produces a perfect maze.

Like I did for the recursive backtracking algorithm, here?s the ?mile-high? overview of Eller?s algorithm:

  1. Initialize the cells of the first row to each exist in their own set.
  2. Now, randomly join adjacent cells, but only if they are not in the same set. When joining adjacent cells, merge the cells of both sets into a single set, indicating that all cells in both sets are now connected (there is a path that connects any two cells in the set).
  3. For each set, randomly create vertical connections downward to the next row. Each remaining set must have at least one vertical connection. The cells in the next row thus connected must share the set of the cell above them.
  4. Flesh out the next row by putting any remaining cells into their own sets.
  5. Repeat until the last row is reached.
  6. For the last row, join all adjacent cells that do not share a set, and omit the vertical connections, and you?re done!

If you?re at all like me, your head is probably spinning at this point. Let?s back up and work through an example manually, to help you see how the algorithm works in practice. Let?s begin with a simple 5-column row.

An example

First, we initialize each cell in that row to be in its own set. I?ll just assign each cell a number, indicating the set it belongs to:

   ___________________
  |   |   |   |   |   |
  | 1 | 2 | 3 | 4 | 5 |
  |___|___|___|___|___|

Next, we randomly join adjacent cells that belong to different sets. The cells so joined also are merged into the same set:

   ___________________
  |           |       |
  | 1   1   1 | 4   4 |
  |___________|_______|

Now we randomly determine the vertical connections, at least one per set. The cells in the next row that we connected to must be assigned to the set of the cell above them:

   ___________________
  |           |       |
  | 1   1   1 | 4   4 |
  |    ___    |___    |
  |   |   |   |   |   |
  | 1 |   | 1 |   | 4 |
  |___|   |___|   |___|

Next, we flesh out the next row, assigning each remaining cell to its own set:

   ___________________
  |           |       |
  | 1   1   1 | 4   4 |
  |    ___    |___    |
  |   |   |   |   |   |
  | 1 | 6 | 1 | 7 | 4 |
  |___|___|___|___|___|

At this point, we can actually discard the first row, because the algorithm is done with it. We?ll keep it around for now, though, for the sake of illustration. I?ll just put a little space between the previous rows, and the current row:

   ___________________
  |           |       |
  | 1   1   1 | 4   4 |
  |    ___    |___    |
       ___     ___
  |   |   |   |   |   |
  | 1 | 6 | 1 | 7 | 4 |
  |___|___|___|___|___|

Now, we just repeat the previous steps on our new row. We randomly connect adjacent sets that do not share a set. Something like this:

       ___     ___
  |       |       |   |
  | 1   1 | 1   1 | 4 |
  |_______|_______|___|

Now we add at least one vertical connection for each set:

       ___     ___
  |       |       |   |
  | 1   1 | 1   1 | 4 |
  |___    |_______|   |
      |   |       |   |
      | 1 |       | 4 |
      |___|       |___|

And then we flesh out the next row (I?m reusing some extinct set numbers here, for the sake of single-digits):

       ___     ___
  |       |       |   |
  | 1   1 | 1   1 | 4 |
  |___    |_______|   |
  |   |   |   |   |   |
  | 8 | 1 | 9 | 2 | 4 |
  |___|___|___|___|___|

This is our current state, with history, now:

   ___________________
  |           |       |
  | 1   1   1 | 4   4 |
  |    ___    |___    |
  |       |       |   |
  | 1   1 | 1   1 | 4 |
  |___    |_______|   |
   ___     ___ ___
  |   |   |   |   |   |
  | 8 | 1 | 9 | 2 | 4 |
  |___|___|___|___|___|

It?s starting to look like a maze! Let?s do one more iteration, and then finish it out. So, first, randomly join adjacent cells from different sets:

   ___     ___ ___
  |   |   |           |
  | 8 | 1 | 9   9   9 |
  |___|___|___ ___ ___|

Then, add at least one veritcal connection for each set:

   ___     ___ ___
  |   |   |           |
  | 8 | 1 | 9   9   9 |
  |   |   |___     ___|
  |   |   |   |   |
  | 8 | 1 |   | 9 |
  |___|___|   |___|

And flesh out the next row:

   ___________________
  |           |       |
  | 1   1   1 | 9   9 |
  |    ___    |___    |
  |       |       |   |
  | 1   1 | 1   1 | 9 |
  |___    |_______|   |
  |   |   |           |
  | 8 | 1 | 9   9   9 |
  |   |   |___     ___|
           ___     ___
  |   |   |   |   |   |
  | 8 | 1 | 3 | 9 | 5 |
  |___|___|___|___|___|

And now the last row. This time, we must connect ALL adjacent (but disjoint) cells. In this case, that means all of them:

           ___     ___
  |                   |
  | 8   8   8   8   8 |
  |___________________|

Since this is the last row, we skip the bit where we add verticals?and that means we?re done! The result, with set numbers removed, is:

   ___________________
  |           |       |
  |           |       |
  |    ___    |___    |
  |       |       |   |
  |       |       |   |
  |___    |_______|   |
  |   |   |           |
  |   |   |           |
  |   |   |___     ___|
  |                   |
  |                   |
  |___________________|

A perfect maze!

Analysis

Let?s analyze that a bit. It seemed to come together pretty magically, considering we weren?t looking at anything but the current row (and the next row, briefly). The key to it all are the sets.

The set that a cell belongs to tells the algorithm who its siblings were, are, and will be. It?s the crystal ball that lets the algorithm gaze into the future (and the past!) and avoid adding cycles and isolates to the maze.

Cells that share a set, also share a path between them. (If you don?t believe me, look at the example I just gave, above. Every cell that shares a set identifier is connected; cells in different sets are not connected.)

If the algorithm allowed us to create a passage between two cells that shared a set, it would be introducing a second path between those two cells. That?s essentially the definition of a loop or cycle in the graph, and since we don?t want cycles in our maze, we disallow that.

Conversely, cells that do not share a set, are not connected (they are disjoint). By the time we reach the end of the maze, every cell must be connected to every other cell, and the only way we can do that is if every set is eventually merged into a single set.

We can?t do that if a set does not propogate itself to the next row. This is why the algorithm requires that at least one vertical passage be created for each set in the row. Otherwise, any set that didn?t create a vertical passage would become extinct after the current row. The result would be an isolate, an orphaned collection of cells that could never be reached from outside that set.

Then, at the end, the algorithm joins all disjoint sets, allowing every cell in the the entire maze to be connected by a single, unique path to any other cell in the maze. And we?re done!

Implementation

How would you implement this? The key, for me, turned out to be implementing the sets. You need to be able to quickly determine the set of any given cell in a row, as well as determine the list of cells in any given set. I did this by maintaining a hash of arrays that mapped sets to cells, and another hash that mapped cells to sets. As I did in the example above, I simply used a unique integer to identify each set.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@sets = Hash.new { |h,k| h[k] = [] }
@cells = {}

def same?(cell1, cell2)
  @cells[cell1] == @cells[cell2]
end

def add(cell, set)
  @cells[cell] = set
  @sets[set] << cell
  self
end

def each_set
  @sets.each do |id, set|
    yield id, set
  end
end

The process of merging two sets is O(n) as I?ve implemented it, but given that n is fairly small, that didn?t worry me too much:

1
2
3
4
5
6
7
def merge(sink_cell, target_cell)
  sink, target = @cells[sink_cell], @cells[target_cell]

  @sets[sink].concat(@sets[target])
  @sets[target].each { |cell| @cells[cell] = sink }
  @sets.delete(target)
end

There?s plenty of room for optimization there, though.

Lastly, assigning set ids is done via a #populate method:

1
2
3
4
5
6
7
8
9
10
11
def populate
  width.times do |cell|
    unless @cells[cell]
      set = @next_set += 1
      @sets[set] << cell
      @cells[cell] = set
    end
  end

  self
end

Once I had these routines (encapsulated into a State class), the algorithm itself came fairly neatly. It works in two steps, plus a third to convert the representation into something easier to display.

The first step looks over the row and randomly connects adjacent cells (if they exist in disjoint sets):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
connected_sets = []
connected_set = [0]

(state.width-1).times do |c|
  if state.same?(c, c+1) || (!finish && rand(2) > 0)
    # cells are not joined by a passage, so we start a new connected set
    connected_sets << connected_set
    connected_set = [c+1]
  else
    state.merge(c, c+1)
    connected_set << c+1
  end
end

connected_sets << connected_set

As you can see, the process simply looks at each cell and its neighbor, comparing their states and then either adding the cells to a ?connected set? (a series of adjacent cells that are all horizontally connected) and merging the sets together, or creating a new connected set when the two cells should not be merged.

The finish variable is used to change the behavior for the final row; it is false for the rest of the rows.

The second step looks at the available sets and randomly adds vertical connections:

1
2
3
4
5
6
7
8
9
10
verticals = []
next_state = state.next

unless finish
  state.each_set do |id, set|
    cells_to_connect = set.sort_by { rand }[0, 1 + rand(set.length-1)]
    verticals.concat(cells_to_connect)
    cells_to_connect.each { |cell| next_state.add(cell, id) }
  end
end

State#next just returns a new State object (that we?re using for the next row). Then, for each set of cells, we randomly pick some number of them and add them to the list of verticals we?re going to create. (The verticals are also added to the next row, in the same set.)

The algorithm itself then loops over these steps repeatedly, setting state to next_state at the end of each pass, until it is done. (In my case, I trapped the INT signal, so ctrl-C can be used to terminate the algorithm and gracefully finish the maze.)

My complete implementation is here:

<noscript>ellers.rb on gist.github.com</noscript>

I think Eller?s algorithm is harder to customize than the recursive backtracking algorithm, but it can be done. Consider it an exercise, if you want: how would you introduce horizontal or vertical bias into the maze? (I.e., how would you make the maze prefer longer corridors, either horizontally or vertically?) How would you implement weave mazes, where the passages move over or under other passages? Especially tricky: how would you introduce symmetry into the output, given that the algorithm itself doesn?t look at anything more than the single row?

If nothing else, though, please give Eller?s algorithm a shot. Please share your implementations (in any language!) in the comments (links to gist.github.com are preferred).

Hendy Irawan: How to Dump/Inspect Object or Variable in Java

Dec 26, 2010

Scala (console) has a very useful feature to inspect or dump variables / object values :

scala> def b = Map("name" -> "Yudha", "age" -> 27)
b: scala.collection.immutable.Map[java.lang.String,Any]

scala> b
res1: scala.collection.immutable.Map[java.lang.String,Any] = Map((name,Yudha), (age,27))

Inside our application, especially in Java programming language (although the techniques below obviously works with any JVM language like Scala and Groovy) sometimes we want to inspect/dump the content of an object/value. Probably for debugging or logging purposes.

My two favorite techniques is just to serialize the Java object to JSON and/or XML. An added benefit is that it’s possible to deserialize the dumped object representation back to an actual object if you want.

JSON Serialization with Jackson

Depend on Jackson (using Maven):
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.6.3</version>
</dependency>
Then use it:
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

..
Logger logger = LoggerFactory.getLogger(getClass());

@Test
public void level() throws ServiceException, JsonGenerationException, JsonMappingException, IOException {
MagentoServiceLocator locator = new MagentoServiceLocator();
Mage_Api_Model_Server_HandlerPortType port = locator.getMage_Api_Model_Server_HandlerPort();
String sessionId = port.login("...", "...");
logger.info(String.format("Session ID = %s", sessionId));
Map[] categories = (Map[]) port.call(sessionId, "catalog_category.level", new Object[] { null, null, 2 } );
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
logger.info( mapper.writeValueAsString(categories) );
}

Example output :

6883 [main] INFO id.co.bippo.shop.magentoclient.AppTest - [ {
? "position" : "1",
? "level" : "2",
? "is_active" : "1",
? "name" : "Gamis",
? "category_id" : "3",
? "parent_id" : 2
}, {
? "position" : "2",
? "level" : "2",
? "is_active" : "1",
? "name" : "Celana",
? "category_id" : "5",
? "parent_id" : 2
} ]

XML Serialization with XStream

As a pre-note, XStream can also handle JSON with either Jettison or its own JSON driver, however people usually prefer Jackson than XStream for JSON serialization.

Maven dependency for XStream:
<dependency>
<groupId>xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.2.2</version>
</dependency>
Use it:
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Map;

import javax.xml.rpc.ServiceException;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.thoughtworks.xstream.XStream;
...
@Test
public void infoXml() throws ServiceException, RemoteException {
MagentoServiceLocator locator = new MagentoServiceLocator();
Mage_Api_Model_Server_HandlerPortType port = locator.getMage_Api_Model_Server_HandlerPort();
String sessionId = port.login("...", "...");
logger.info(String.format("Session ID = %s", sessionId));
Map category = (Map) port.call(sessionId, "catalog_category.info",
new Object[] { 3 } );
XStream xstream = new XStream();
logger.info( xstream.toXML(category) );
}

Sample output:

5949 [main] INFO id.co.bippo.shop.magentoclient.AppTest - <map>
? <entry>
??? <string>position</string>
??? <string>1</string>
? </entry>
? <entry>
??? <string>custom_design</string>
??? <string></string>
? </entry>
? <entry>
??? <string>custom_use_parent_settings</string>
??? <string>0</string>
? </entry>
? <entry>
??? <string>custom_layout_update</string>
??? <string></string>
? </entry>
? <entry>
??? <string>include_in_menu</string>
??? <string>1</string>
? </entry>
? <entry>
??? <string>custom_apply_to_products</string>
??? <string>0</string>
? </entry>
? <entry>
??? <string>meta_keywords</string>
??? <string>gamis, busana muslim</string>
? </entry>
? <entry>
??? <string>available_sort_by</string>
??? <string></string>
? </entry>
? <entry>
??? <string>url_path</string>
??? <string>gamis.html</string>
? </entry>
? <entry>
??? <string>children</string>
??? <string></string>
? </entry>
? <entry>
??? <string>landing_page</string>
??? <null/>
? </entry>
? <entry>
??? <string>display_mode</string>
??? <string>PRODUCTS</string>
? </entry>
? <entry>
??? <string>level</string>
??? <string>2</string>
? </entry>
? <entry>
??? <string>description</string>
??? <string>Gamis untuk muslimah</string>
? </entry>
? <entry>
??? <string>name</string>
??? <string>Gamis</string>
? </entry>
? <entry>
??? <string>path</string>
??? <string>1/2/3</string>
? </entry>
? <entry>
??? <string>created_at</string>
??? <string>2010-12-24 11:37:41</string>
? </entry>
? <entry>
??? <string>children_count</string>
??? <string>0</string>
? </entry>
? <entry>
??? <string>is_anchor</string>
??? <string>1</string>
? </entry>
? <entry>
??? <string>url_key</string>
??? <string>gamis</string>
? </entry>
? <entry>
??? <string>parent_id</string>
??? <int>2</int>
? </entry>
? <entry>
??? <string>filter_price_range</string>
??? <null/>
? </entry>
? <entry>
??? <string>all_children</string>
??? <string>3</string>
? </entry>
? <entry>
??? <string>is_active</string>
??? <string>1</string>
? </entry>
? <entry>
??? <string>page_layout</string>
??? <string></string>
? </entry>
? <entry>
??? <string>image</string>
??? <null/>
? </entry>
? <entry>
??? <string>category_id</string>
??? <string>3</string>
? </entry>
? <entry>
??? <string>default_sort_by</string>
??? <null/>
? </entry>
? <entry>
??? <string>custom_design_from</string>
??? <null/>
? </entry>
? <entry>
??? <string>updated_at</string>
??? <string>2010-12-24 11:37:41</string>
? </entry>
? <entry>
??? <string>meta_description</string>
??? <string>Jual baju gamis untuk muslim</string>
? </entry>
? <entry>
??? <string>custom_design_to</string>
??? <null/>
? </entry>
? <entry>
??? <string>path_in_store</string>
??? <null/>
? </entry>
? <entry>
??? <string>meta_title</string>
??? <string>Gamis</string>
? </entry>
? <entry>
??? <string>increment_id</string>
??? <null/>
? </entry>
</map>

Which one is better?

I personally prefer JSON, but fortunately, you always have a choice. :-)

Ubuntu Upstart for automatic MySQL start and stop

Dec 25, 2010

Here at Recorded Future we use Ubuntu (running on Amazon EC2), but so far we have not explored Ubuntu Upstart that much. During the holidays I made an effort to get acquainted with Upstart and to implement proper MySQL start and stop with it.If you do not know Upstart, this is the way you start and stop services in Ubuntu, and it serves the same purpose as the old /etc/init.d scripts, but are a bit more structured and powerful. That said, Upstart is regrettably far from complete, although the functionality is much better and Upstart has some cool features, some things do not work that well. For one thing, documentation, where it exists, is useless, at best. Secondly, there is very limited ability to test and develop Upstart scripts. And this is made worse by the fact that the documentation is so bad. Another thing is that Upstart insist on stopping services, by default, by sending a brutal kill signal. Not good for databases, mostly.In the /etc/init directory are the Upstart scripts you have. In difference to the old init.d scripts, you cannot disable a service in Upstart curenntly. If it is in /etc/init it will be started at system start. That’s it. And this is something that I am sure will be fixed, but for now, again, is something we have to live with. Upstart scripts have the suffix .conf (don’t ask me why), so the default MySQL Upstart script, for example, is called /etc/init/mysql.conf.In an Upstart script, there are Stanzas that determine what to do. Like the exec Stanza that runs a program for example. And you may then ask, when is it run? Startup? Shutdown? And the answer is startup. For shutting things down, as I said before, Upstart will by default just send a kill -9 signal.The minimal startup script you can have, and this actually works in a reasonable way, is to just have one line with an exec stanza, like this:exec /usr/bin/mydaemonWhich will start the daemon. For stopping the daemon, Upstart will send a -9 signal to the started process by default, and nothing more is needed in the Upstart script.For MySQL, we need to make things a bit more complicated. The default mysql.conf Upstart script really is not good. For one thing, it will not do a controlled shutdown of MySQL (this is possible even if Upstart will eventually send a kill -9 anyway). Secondly, this script assumes that what we use is a standard Ubunty installed MySQL distribution, so if you have installed MySQL in /usr/bin/mysql5147 or somethings like that, you are out of luck.So what I wanted to create was an Upstart script for MySQL that fullfilled these requirements:Starts MySQL automatically.Waits for MySQL to be available before exiting.Be configurable to support different MySQL install locations, data directories etc.Do a clean shutdown of MySQL when stopping the MySQL services.Before I show you what I ended up with, I want to comment on the points 2 and 4 above. With Upstart, you can define a script or command to run just before or after a services has been started or stopped, and this is what I use to wait for MySQL to become available, and to send a SIGTERM to the MySQL Server when stopping (which will do a clean MySQL shutdown).So here we go, a complete MySQL Upstart script, the way I want it to work:## MySQL Service for Recorded Future#description “MySQL Server”author “Anders Karlsson, Recorded Future”start on (net-device-up and local-filesystems and runlevel [2345])stop on runlevel [016]expect forkkill timeout 2# Set variables.env MYSQL_ETC=/etc/mysqlenv MYSQL_PIDFILE=/var/run/mysql.pidenv MYSQL_HOME=/usr/local/mysql5.5env MYSQL_INSTANCE=myumask 007exec $MYSQL_HOME/bin/mysqld_safe –defaults-file=$MYSQL_ETC/$MYSQL_INSTANCE.cnf >> /tmp/x.out &post-start script loop=600# Wait for MySQL to start. while [ $loop -gt 0 ]; do if $MYSQL_HOME/bin/mysqladmin –defaults-file=$MYSQL_ETC/$MYSQL_INSTANCE.cnf ping; then break fi loop=$(($loop – 1)) sleep 1 done exit 0end script# Send a soft SIGTERM to MySQL before Upstart will kill it.# A Sigterm to mysqld will cause a controlled shutdown.pre-stop script exec kill -SIGTERM `cat $MYSQL_PIDFILE`# Wait for MySQL to end. Flushing buffers and all. loop=600 while [ $loop -gt 0 ]; do# If the pidfile is found, then continue waiting. if [ -e $MYSQL_PIDFILE ] ; then loop=$((loop – 1)) sleep 1 continue fi break doneend scriptTo be honest, this is not what I create for all our MySQL servers. Instead I used this to create a chef template, chef is what we use for configuration management here (see http://www.opscode.com/ for more on chef), and here it is put to good ude to generate an Upstart script for MySQL. The above is just an example./Karlsson