2015-09-11

Jony Ive, please, fix this

I agree with every single word of this eloquent critique of the seriously wrong direction taken by Apple in the user-interface design of iOS 7, 8, and 9.

2015-09-05

SQL-99 Book

The MariaDB.com (MySQL) site provides an online version of the very nice book SQL-99 Complete, Really book by Peter Gulutzan & Trudy Pelzer, the best SQL reference book I’ve seen. This book is based on standard SQL, not specific to MySQL. Story here.

2015-07-19

Cool MacBook Workstation

I mean cool literally. Apple designed the MacBook Pro laptop to run cool for basic use. But if you start pushing hard on those cores, it heats up like a hot potato. Add some ambient heat and you'll hear those little internal fans blowing a mighty wind. Electronics hate the heat, so is there a way we can make life easier for our faithful servant MacBooks?

# 1 – Roost


First step, get yourself one of the handy-dandy laptop-lifting wonders: the Roost.



This clever invention is lightweight, mighty strong, easy to pack in my nifty Brenthaven SlimPack, and quick to setup/teardown.

I have the original Roost. You may have to wait to get the new design,  shipping in November 2015. Hopefully better than ever, but their first design was already perfect in my mind.

# 2 – Fan


The modern MacBooks are designed to shed heat through their metal frame and casing. Move some air past that metal and you'll greatly enhance the cooling effect.

So how to move air beneath your MacBook? Well, notice in that picture of the Roost how the derrière is raised upwards? Perfect positioning to place a small angled fan beneath, blowing a steady stream of air into the bottom case of your laptop. You need only a small fan, like the Insignia™ - High-Velocity 4" Mini Fan at BestBuy.com.

Cost? Six bucks on sale now. Usually USD $ 10.

Available in white, blue, or sorbet (pink).

 

The cage pivots to swing the fan upwards. You can easily adjust it to hit your MacBook.

The fan does make some noise, a steady buzz, similar to the quieter versions of fans found in the old tower computers of yore. May be a tad louder than the MacBook’s own fans. The sound seems physical, apparently the moving of the blades, and much less annoying than an electronic hum. 

The small motor has some unexpected heft, hopefully will prove reliable. Has a metal cage and shiny metal blades rather than crude plastic. Moves just the right amount of air to keep the MacBook cool and its internal fans off while not disturbing me or my papers.



2015-06-18

How many SQL keywords?

Collisions between your table/column names and SQL reserved keywords is easier than you might think. Much easier.

Pop Quiz

Here's a list of words I could easily imagine using as column names. Can you pick out which are reserved by either the SQL standard or by proprietary extensions of various database products?

KEY
UNIQUE

EXISTS
PLAN

USER
VIEW
WORK

POSITION
TOP
LEFT
RIGHT
UPPER

OPEN
CLOSE
OUTPUT
FILE

SIZE
ADD
DELETE
MATCH

HOST
GROUP
EXTERNAL


STATISTICS
PROCEDURE
VALUES
REFERENCES
SCOPE

BULK
NATURAL

FOREIGN
PUBLIC
GLOBAL
LANGUAGE
MAP

FOUND
HOLD
FREE

ORDER
LINENO
TRANSACTION

LOAD
CASE
SET
PARTIAL
SECTION
PERCENT


HOUR
MONTH
YEAR
DATE
TIME
CURRENT
ZONE


Trick question. All of those are reserved.

Some brief digging around on the Internet, found me plenty of keywords, most of them reserved or possibly causing problems if used as your own identifiers in naming tables, columns, indexes, constraints, functions, and so on.

I wrote a little Java app to eliminate duplicates. How many did I find? Over a thousand! Exact total: 1,131. I would bet money you can find more. See the full list below.

Trailing Underscore

Tip: Avoid such collisions by giving all your SQL identifiers (names of columns, tables, indexes, constraints, and such) a trailing underscore.

Examples: "person_", "invoice_", "date_of_birth_".

The SQL standard explicitly promises to never use a trailing underscore in any name, keyword, or other SQL-related context.

List Of Reserved Keywords

The following list an intersection of these three lists:

A
ABORT
ABS
ABSENT
ABSOLUTE
ACCESS
ACCORDING
ACOS
ACQUIRE
ACTION
ADA
ADD
ADMIN
AFTER
AGGREGATE
ALIAS
ALL
ALLOCATE
ALSO
ALTER
ALWAYS
ANALYSE
ANALYZE
AND
ANY
ARE
ARITH_OVERFLOW
ARRAY
ARRAY_AGG
ARRAY_MAX_CARDINALITY
AS
ASC
ASCII
ASENSITIVE
ASIN
ASSERTION
ASSIGNMENT
ASYMMETRIC
AT
ATAN
ATAN2
ATOMIC
ATTRIBUTE
ATTRIBUTES
AUDIT
AUTHORIZATION
AUTO_INCREMENT
AVG
AVG_ROW_LENGTH
BACKUP
BACKWARD
BASE64
BEFORE
BEGIN
BEGIN_FRAME
BEGIN_PARTITION
BERNOULLI
BETWEEN
BIGINT
BINARY
BIT
BITVAR
BIT_LENGTH
BLOB
BLOCKED
BOM
BOOL
BOOLEAN
BOTH
BREADTH
BREAK
BROWSE
BUFFERPOOL
BULK
BY
C
CACHE
CALL
CALLED
CAPTURE
CARDINALITY
CASCADE
CASCADED
CASE
CAST
CATALOG
CATALOG_NAME
CCSID
CEIL
CEILING
CHAIN
CHANGE
CHAR
CHARACTER
CHARACTERISTICS
CHARACTERS
CHARACTER_LENGTH
CHARACTER_SET_CATALOG
CHARACTER_SET_NAME
CHARACTER_SET_SCHEMA
CHARINDEX
CHAR_CONVERT
CHAR_LENGTH
CHECK
CHECKED
CHECKPOINT
CHECKSUM
CHILD
CHR
CLASS
CLASS_ORIGIN
CLOB
CLOSE
CLUSTER
CLUSTERED
COALESCE
COBOL
COLLATE
COLLATION
COLLATION                       d
COLLATION_CATALOG
COLLATION_NAME
COLLATION_SCHEMA
COLLECT
COLLECTION
COLUMN
COLUMNS
COLUMN_NAME
COMMAND_FUNCTION
COMMAND_FUNCTION_CODE
COMMENT
COMMENTS
COMMIT
COMMITTED
COMPLETION
COMPRESS
COMPUTE
CONCAT
CONCURRENTLY
CONDITION
CONDITION_NUMBER
CONFIGURATION
CONFIRM
CONNECT
CONNECTION
CONNECTIONS
CONNECTION_NAME
CONSTRAINT
CONSTRAINTS
CONSTRAINT_CATALOG
CONSTRAINT_NAME
CONSTRAINT_SCHEMA
CONSTRUCTOR
CONTAINS
CONTAINSTABLE
CONTENT
CONTINUE
CONTROL
CONTROLROW
CONVERSION
CONVERT
COPY
CORR
CORRESPONDING
COS
COST
COUNT
COVAR_POP
COVAR_SAMP
CREATE
CREATEDB
CREATEROLE
CREATEUSER
CROSS
CSV
CUBE
CUME_DIST
CURRENT
CURRENT_CATALOG
CURRENT_DATE
CURRENT_DEFAULT_TRANSFORM_GROUP
CURRENT_PATH
CURRENT_ROLE
CURRENT_ROW
CURRENT_SCHEMA
CURRENT_SERVER
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIMEZONE
CURRENT_TRANSFORM_GROUP_FOR_TYPE
CURRENT_USER
CURSOR
CURSOR_NAME
CYCLE
DAT
DATA
DATA-PGS
DATABASE
DATABASES
DATALINK
DATE
DATETIME
DATETIME_INTERVAL_CODE
DATETIME_INTERVAL_PRECISION
DAY
DAYOFMONTH
DAYOFWEEK
DAYOFYEAR
DAYS
DAY_HOUR
DAY_MICROSECOND
DAY_MINUTE
DAY_SECOND
DB
DBA
DBCC
DBSPACE
DEALLOCATE
DEC
DECIMAL
DECLARE
DEFAULT
DEFAULTS
DEFERRABLE
DEFERRED
DEFINED
DEFINER
DEGREE
DELAYED
DELAY_KEY_WRITE
DELETE
DELIMITER
DELIMITERS
DENSE_RANK
DENY
DEPTH
DEREF
DERIVED
DESC
DESCRIBE
DESCRIPTOR
DESTROY
DESTRUCTOR
DETERMINISTIC
DIAGNOSTICS
DICTIONARY
DIM
DISABLE
DISCARD
DISCONNECT
DISK
DISPATCH
DISTINCT
DISTINCTROW
DISTRIBUTED
DIV
DLNEWCOPY
DLPREVIOUSCOPY
DLURLCOMPLETE
DLURLCOMPLETEONLY
DLURLCOMPLETEWRITE
DLURLPATH
DLURLPATHONLY
DLURLPATHWRITE
DLURLSCHEME
DLURLSERVER
DLVALUE
DO
DOCUMENT
DOMAIN
DOUBLE
DROP
DTCY
DTD
DTM
DTW
DTY
DUAL
DUMMY
DUMP
DYNAMIC
DYNAMIC_FUNCTION
DYNAMIC_FUNCTION_CODE
EACH
EDITPROC
ELEMENT
ELSE
ELSEIF
EMPTY
ENABLE
ENCLOSED
ENCODING
ENCRYPTED
END
END-EXEC
ENDTRAN
END_FRAME
END_PARTITION
ENFORCED
ENUM
EQUALS
ERASE
ERRLEVEL
ERRLVL
ERROREXIT
ESCAPE
ESCAPED
EVENT
EVERY
EXCEPT
EXCEPTION
EXCLUDE
EXCLUDING
EXCLUSIVE
EXEC
EXECUTE
EXISTING
EXISTS
EXIT
EXP
EXPLAIN
EXPRESSION
EXTENSION
EXTERNAL
EXTRACT
FALSE
FAMILY
FETCH
FIELDPROC
FIELDS
FILE
FILLFACTOR
FILTER
FINAL
FIRST
FIRST_VALUE
FLAG
FLOAT
FLOAT4
FLOAT8
FLOAT_TYPE
FLOOR
FLUSH
FOLLOWING
FOR
FORCE
FOREIGN
FORTRAN
FORWARD
FOUND
FRAME_ROW
FREE
FREETEXT
FREETEXTTABLE
FREEZE
FROM
FS
FULL
FULLTEXT
FUNCTION
FUNCTIONS
FUSION
G
GENERAL
GENERATED
GET
GLOBAL
GO
GOTO
GRANT
GRANTED
GRANTS
GRAPHIC
GREATEST
GROUP
GROUPING
GROUPS
HANDLER
HAVING
HEADER
HEAP
HEX
HIERARCHY
HIGH_PRIORITY
HOLD
HOLDLOCK
HOST
HOSTS
HOUR
HOURS
HOUR_MICROSECOND
HOUR_MINUTE
HOUR_SECOND
ID
IDENTIFIED
IDENTITY
IDENTITYCOL
IDENTITY_INSERT
IF
IGNORE
ILIKE
IMMEDIATE
IMMEDIATELY
IMMUTABLE
IMPLEMENTATION
IMPLICIT
IMPORT
IN
INCLUDE
INCLUDING
INCREMENT
INDENT
INDEX
INDEXES
INDICATOR
INFILE
INFIX
INHERIT
INHERITS
INITCAP
INITIAL
INITIALIZE
INITIALLY
INLINE
INNER
INOUT
INPUT
INSENSITIVE
INSERT
INSERT_ID
INSTANCE
INSTANTIABLE
INSTEAD
INT
INT1
INT2
INT3
INT4
INT8
INTEGER
INTEGRITY
INTERSECT
INTERSECTION
INTERVAL
INTO
INVOKER
IS
ISAM
ISNULL
ISOLATION
ITERATE
JOIN
K
KEY
KEYS
KEY_MEMBER
KEY_TYPE
KILL
LABEL
LAG
LANCOMPILER
LANGUAGE
LARGE
LAST
LAST_INSERT_ID
LAST_VALUE
LATERAL
LC_COLLATE
LC_CTYPE
LEAD
LEADING
LEAKPROOF
LEAST
LEAVE
LEFT
LENGTH
LESS
LEVEL
LIBRARY
LIKE
LIKE_REGEX
LIMIT
LINENO
LINES
LINK
LIST
LISTEN
LN
LOAD
LOCAL
LOCALTIME
LOCALTIMESTAMP
LOCATION
LOCATOR
LOCK
LOCKSIIZE
LOG
LOG10
LOGIN
LOGS
LONG
LONGBLOB
LONGTEXT
LOOP
LOWER
LOW_PRIORITY
M
MAP
MAPPING
MATCH
MATCHED
MATERIALIZED
MAX
MAXEXTENTS
MAXVALUE
MAX_CARDINALITY
MAX_ROWS
MEDIUMBLOB
MEDIUMINT
MEDIUMTEXT
MEMBER
MERGE
MESSAGE_LENGTH
MESSAGE_OCTET_LENGTH
MESSAGE_TEXT
METHOD
MICROSECOND
MICROSECONDS
MIDDLEINT
MIN
MINUS
MINUTE
MINUTES
MINUTE_MICROSECOND
MINUTE_SECOND
MINVALUE
MIN_ROWS
MIRROR
MIRROREXIT
MLSLABEL
MOD
MODE
MODIFIES
MODIFY
MODULE
MONTH
MONTHNAME
MONTHS
MORE
MOVE
MULTISET
MUMPS
MYISAM
NAME
NAMED
NAMES
NAMESPACE
NATIONAL
NATURAL
NCHAR
NCLOB
NESTING
NEW
NEXT
NFC
NFD
NFKC
NFKD
NHEADER
NIL
NO
NOAUDIT
NOCHECK
NOCOMPRESS
NOCREATEDB
NOCREATEROLE
NOCREATEUSER
NOHOLDLOCK
NOINHERIT
NOLOGIN
NONCLUSTERED
NONE
NORMALIZE
NORMALIZED
NOSUPERUSER
NOT
NOTHING
NOTIFY
NOTNULL
NOWAIT
NO_WRITE_TO_BINLOG
NTH_VALUE
NTILE
NULL
NULLABLE
NULLIF
NULLS
NUMBER
NUMERIC
NUMERIC_TRUNCATION
NUMPARTS
OBID
OBJECT
OCCURRENCES_REGEX
OCTETS
OCTET_LENGTH
OF
OFF
OFFLINE
OFFSET
OFFSETS
OIDS
OLD
ON
ONCE
ONLINE
ONLY
OPEN
OPENDATASOURCE
OPENQUERY
OPENROWSET
OPENXML
OPERATION
OPERATOR
OPTIMIZE
OPTION
OPTIONALLY
OPTIONS
OR
ORDER
ORDERING
ORDINALITY
OTHERS
OUT
OUTER
OUTFILE
OUTPUT
OVER
OVERLAPS
OVERLAY
OVERRIDING
OWNED
OWNER
P
PACKAGE
PACK_KEYS
PAD
PAGE
PAGES
PARAMETER
PARAMETERS
PARAMETER_MODE
PARAMETER_NAME
PARAMETER_ORDINAL_POSITION
PARAMETER_SPECIFIC_CATALOG
PARAMETER_SPECIFIC_NAME
PARAMETER_SPECIFIC_SCHEMA
PARENT
PARSER
PART
PARTIAL
PARTITION
PASCAL
PASSING
PASSTHROUGH
PASSWORD
PATH
PCTFREE
PCTINDEX
PERCENT
PERCENTILE_CONT
PERCENTILE_DISC
PERCENT_RANK
PERIOD
PERM
PERMANENT
PERMISSION
PICTURE
PIVOT
PLACING
PLAN
PLANS
PLI
PORTION
POSITION
POSITION_REGEX
POSTFIX
POWER
PRECEDES
PRECEDING
PRECISION
PREFIX
PREORDER
PREPARE
PREPARED
PRESERVE
PRIMARY
PRINT
PRIOR
PRIVATE
PRIVILEGES
PROC
PROCEDURAL
PROCEDURE
PROCEDUREALL
PROCESS
PROCESSEXIT
PROCESSLIST
PROGRAM
PUBLIC
PUBLICALTER
PURGE
QUOTE
RAID0
RAISERROR
RAISERRORAND
RANGE
RANK
RAW
READ
READANY
READS
READTEXT
READTEXTAS
REAL
REASSIGN
RECHECK
RECONFIGURE
RECONFIGUREASC
RECOVERY
RECURSIVE
REF
REFERENCES
REFERENCESAUTHORIZATION
REFERENCING
REFRESH
REGEXP
REGR_AVGX
REGR_AVGY
REGR_COUNT
REGR_INTERCEPT
REGR_R2
REGR_SLOPE
REGR_SXX
REGR_SXY
REGR_SYY
REINDEX
RELATIVE
RELEASE
RELOAD
RENAME
REPEAT
REPEATABLE
REPLACE
REPLICA
REPLICATION
REPLICATIONBACKUP
REQUIRE
REQUIRING
RESERVED_PAGES
RESET
RESIGNAL
RESOURCE
RESPECT
RESTART
RESTORE
RESTOREBEGIN
RESTRICT
RESTRICTBETWEEN
RESULT
RETURN
RETURNBREAK
RETURNED_CARDINALITY
RETURNED_LENGTH
RETURNED_OCTET_LENGTH
RETURNED_SQLSTATE
RETURNING
RETURNS
REVERTBROWSE
REVOKE
REVOKEBULK
RIGHT
RIGHTBY
RLIKE
ROLE
ROLLBACK
ROLLBACKCASCADE
ROLLUP
ROUND
ROUTINE
ROUTINE_CATALOG
ROUTINE_NAME
ROUTINE_SCHEMA
ROW
ROWCNT
ROWCOUNT
ROWCOUNTCASE
ROWGUIDCOL
ROWGUIDCOLCHECK
ROWID
ROWLABEL
ROWNUM
ROWS
ROW_COUNT
ROW_NUMBER
RRN
RULE
RULECHECKPOINT
RUN
SAVE
SAVECLOSE
SAVEPOINT
SCALE
SCHEDULE
SCHEMA
SCHEMACLUSTERED
SCHEMAS
SCHEMA_NAME
SCOPE
SCOPE_CATALOG
SCOPE_NAME
SCOPE_SCHEMA
SCROLL
SEARCH
SECOND
SECONDS
SECOND_MICROSECOND
SECQTY SECTION
SECTION
SECURITY
SECURITYAUDITCOALESCE
SELECT
SELECTCOLLATE
SELECTIVE
SELF
SEMANTICKEYPHRASETABLECOLUMN
SEMANTICSIMILARITYDETAILSTABLECOMMIT
SEMANTICSIMILARITYTABLECOMPUTE
SENSITIVE
SEPARATOR
SEQUENCE
SEQUENCES
SEQUENCE_TYPE
SERIALIZABLE
SERVER
SERVER_NAME
SESSION
SESSION_USER
SESSION_USERCONSTRAINT
SET
SETCONTAINS
SETOF
SETS
SETUSER
SETUSERCONTAINSTABLE
SHARE
SHARED
SHOW
SHUTDOWN
SHUTDOWNCONTINUE
SIGNAL
SIMILAR
SIMPLE
SIN
SIZE
SMALLINT
SNAPSHOT
SOME
SOMECONVERT
SONAME
SOURCE
SPACE
SPATIAL
SPECIFIC
SPECIFICTYPE
SPECIFIC_NAME
SQL
SQLCA
SQLCODE
SQLERRM
SQLERROR
SQLEXCEPTION
SQLSTATE
SQLWARNING
SQL_BIG_RESULT
SQL_BIG_SELECTS
SQL_BIG_TABLES
SQL_CALC_FOUND_ROWS
SQL_LOG_OFF
SQL_LOG_UPDATE
SQL_LOW_PRIORITY_UPDATES
SQL_SELECT_LIMIT
SQL_SMALL_RESULT
SQL_WARNINGS
SQRT
SSL
STABLE
STANDALONE
START
STARTING
STATE
STATEMENT
STATIC
STATISTICS
STATISTICSCREATE
STATUS
STDDEV_POP
STDDEV_SAMP
STDIN
STDOUT
STOGROUP
STOPOOL
STORAGE
STRAIGHT_JOIN
STRICT
STRING
STRIP
STRIPE SUBPAGES
STRUCTURE
STYLE
SUBCLASS_ORIGIN
SUBLIST
SUBMULTISET
SUBSTR
SUBSTRING
SUBSTRING_REGEX
SUCCEEDS
SUCCESSFUL
SUM
SUPERUSER
SYB_IDENTITY
SYB_RESTREE
SYMMETRIC
SYNONYM
SYSDATE
SYSID
SYSTEM
SYSTEM_TIME
SYSTEM_USER
SYSTEM_USERCROSS
T
TABLE
TABLECURRENT
TABLES
TABLESAMPLE
TABLESAMPLECURRENT_DATE
TABLESPACE
TABLE_NAME
TAN
TEMP
TEMPLATE
TEMPORARY
TERMINATE
TERMINATED
TEXT
TEXTSIZE
TEXTSIZECURRENT_TIME
THAN
THEN
THENCURRENT_TIMESTAMP
TIES
TIME
TIMESTAMP
TIMEZONE_HOUR
TIMEZONE_MINUTE
TINYBLOB
TINYINT
TINYTEXT
TO
TOAST
TOCURRENT_USER
TOKEN
TOP
TOPCURSOR
TOP_LEVEL_COUNT
TRAILING
TRAN
TRANDATABASE
TRANSACTION
TRANSACTIONDBCC
TRANSACTIONS_COMMITTED
TRANSACTIONS_ROLLED_BACK
TRANSACTION_ACTIVE
TRANSFORM
TRANSFORMS
TRANSLATE
TRANSLATE_REGEX
TRANSLATION
TRANSLATION TRIGGER
TREAT
TRIGGER
TRIGGERDEALLOCATE
TRIGGER_CATALOG
TRIGGER_NAME
TRIGGER_SCHEMA
TRIM
TRIM_ARRAY
TRUE
TRUNCATE
TRUNCATEDECLARE
TRUSTED
TRY_CONVERTDEFAULT
TSEQUAL
TSEQUALDELETE
TYPE
TYPES
UESCAPE
UID
UNBOUNDED
UNCOMMITTED
UNDER
UNDO
UNENCRYPTED
UNION
UNIONDENY
UNIQUE
UNIQUEDESC
UNKNOWN
UNLINK
UNLISTEN
UNLOCK
UNLOGGED
UNNAMED
UNNEST
UNPIVOTDISK
UNSIGNED
UNTIL
UNTYPED
UPDATE
UPDATEDISTINCT
UPDATETEXT
UPDATETEXTDISTRIBUTED
UPPER
URI
USAGE
USE
USEDOUBLE
USED_PGS
USER
USERDROP
USER_DEFINED_TYPE_CATALOG
USER_DEFINED_TYPE_CODE
USER_DEFINED_TYPE_NAME
USER_DEFINED_TYPE_SCHEMA
USER_OPTION
USING
UTC_DATE
UTC_TIME
UTC_TIMESTAMP
VACUUM
VALID
VALIDATE
VALIDATOR
VALIDPROC
VALUE
VALUES
VALUESDUMP
VALUE_OF
VARBINARY
VARCHAR
VARCHAR2
VARCHARACTER
VARIABLE
VARIABLES
VARIADIC
VARYING
VARYINGELSE
VAR_POP
VAR_SAMP
VCAT
VERBOSE
VERSION
VERSIONING
VIEW
VIEWEND
VIEWS
VOLATILE
VOLUMES
WAITFOR
WAITFORERRLVL
WHEN
WHENESCAPE
WHENEVER
WHERE
WHEREEXCEPT
WHILE
WHILEEXEC
WHITESPACE
WIDTH_BUCKET
WINDOW
WITH
WITHEXECUTE
WITHIN
WITHIN GROUPEXISTS
WITHOUT
WORK
WRAPPER
WRITE
WRITETEXT
WRITETEXTEXIT
X509
XML
XMLAGG
XMLATTRIBUTES
XMLBINARY
XMLCAST
XMLCOMMENT
XMLCONCAT
XMLDECLARATION
XMLDOCUMENT
XMLELEMENT
XMLEXISTS
XMLFOREST
XMLITERATE
XMLNAMESPACES
XMLPARSE
XMLPI
XMLQUERY
XMLROOT
XMLSCHEMA
XMLSERIALIZE
XMLTABLE
XMLTEXT
XMLVALIDATE
XOR
YEAR
YEARS
YEAR_MONTH
YES
ZEROFILL
ZONE


 -- fin --

2015-04-27

Tomcat Memory

Modern Java supports 64-bit architectures. That means you can throw many gigs of memory at Tomcat.

This is especially useful in Vaadin apps as the state all lives in web sessions in the Tomcat server. So those sessions tend to eat up memory.

My research into this topic was long and frustrating. For one thing, much discussion involves "PermGen" which is now outmoded. Current updates to Java 8 have eliminated the PermGen, so memory management is now more straightforward.

Eventually I learned one simple way to allocate memory to Tomcat 8. The following steps work on with the Oracle release of Java 8 on Mac OS X Mountain Lion. The steps probably work on any Unix-oriented system such as BSD or Linux. Don’t know about Microsoft Windows. The "-X" flags are optional, not required by the Java spec; so other non-Oracle implementations of Java may not respect these flags.

  1. Locate your Tomcat folder, and the nested the "bin" folder.
  2. Create a text file named exactly "setenv.sh". 
  3. Add one line to the file:
    export JAVA_OPTS="-Xms6144m -Xmx6144m"
Those two numbers should be what ever number of megs you want. So 6,144 megs is 6 gigs. I don’t know if it is required, but I would use multiples of 1024. So 6 * 1024 = 6,144.

By setting the minimum (Xms) to be the same number as the maximum (Xmx), Tomcat will grab and hold that entire amount of memory. If you set the minimum to be lower, you will see the amount of memory used by Tomcat grow and shrink over time as garbage collection releases memory back to the operating system. I do not know the pros and cons of these two behaviors.

2015-03-31

Questions About New Grid Widget In Vaadin 7.4

• Can I set tooltips for the grid headers (column titles)? It is common to use abbreviations for the displayed title while wanting to show the expanded full title in a tooltip.

• Similarly, can grid cell values have a tooltip? It would be nice to attach explanatory  or additional info in a tooltip while keeping the displayed cell content short (abbreviated, or coded).

• Does Grid slow down my app in Vaadin 7.4.2? Since I upgraded to 7.4 from 7.3, my app now displays the yellow and red spinning wheels more often.

• Calling "setContainerDataSource" and passing a new container has no effect on displayed data. The documentation is sparse. Is this a bug; should setting the container cause that container's data to be displayed on screen in place of the old data? Is there some other command I am supposed to call to get the data displayed? In contrast, keeping the same container while removing all items and then adding a collection of items does indeed automatically cause the grid to display fresh data.

2015-02-19

Helping NetBeans and Tomcat Get Along Together

I use NetBeans 8.0.2 with Tomcat 8.0.18 for developing web apps in Vaadin 7.

Generally NetBeans and Tomcat work well together. But I have learned how to workaround a pair of annoying problems.

Session Persistence


The first problem is session persistence. By default, Tomcat attempts to serialize all active sessions’ data. Serialization means extracting the data values from each session’s graph of objects and then writing those values to storage. Serializing sessions enables two uses: (a) re-create any remaining sessions when a server restarts, and (b) enable "clustering" where sessions can be moved between multiple Tomcat servers either for fail-over or for load-balancing.

Those sessions’ graph of objects includes all the objects in your Vaadin app. If you fail to make all your classes serializable, then Tomcat reports errors when shutting down and/or starting up.

If you don't care about (a) and (b) above, then you have no need for persistence of sessions and no need to bother making your app’s classes serializable. But how to stop Tomcat from trying and failing to persist sessions?

As described at the bottom of Tomcat’s Manager documentation page, you can add a single line to your "context.xml" file. That file was created for you by the Vaadin plugin or Maven archetype when your project was created. In a Maven multi-module project, look within the "-ui" submodule > Web Pages > META-INF > context.xml. Change this:

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/MyAppName-ui"/>

to this, adding a "Manager" tag:

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/MyAppName-ui">
    <Manager pathname="" />
</Context>

Multi-Launching


A more troublesome problem with NetBeans+Tomcat is that your Vaadin app is "double-launched". The app launches, shuts down, and launches again. At the very least this makes reading of the log confusing. Even worse, bad side-effects can happen especially if you launch daemon threads in the background. 

Let me be clear: This is only a development problem, a side-effect of combining NetBeans with Tomcat. In production with Tomcat alone, no problem.

The cure is deletion of an XML file that represents the running of your app. Every time NetBeans finishes running your app, delete that file before running again. That file is the name of your app plus ".xml", found in the path: "conf/Catalina/localhost" within your Tomcat's "Cataline Base" folder.

See this Question, Tomcat deploying the same application twice in netbeans, on StackOverflow.com for discussion. See my Answer for my version of others’ code that finds and deletes that .xml each time you stop running your Vaadin app from NetBeans.

2015-01-05

Event Bus For Java

An event bus is a software library used for objects to message each other indirectly. Some objects register with the bus to be notified when certain events of interest occur. And some post events on the bus. The bus itself notifies each of the registrants when the event is posted. So the registrant objects and the event-source objects need not know about each other directly. Each may join or depart the bus at any time. You can think of it as a "pub-sub" publish-subscribe system, but internal to a single app.

The word ‘bus’ plays off the idea of a computer bus where hardware components in a computer system communicate with one another.

An event bus is an alternative to the Observer pattern, as seen in Swing and other Java libraries where called event listeners.

Guava EventBus


The most commonly known event bus for Java is probably the EventBus library included as part of Google Guava. Guava is filled with many handy pieces of goodness.

Unfortunately, the Guava EventBus library inexplicably holds strong references to the registered objects. That means the calling programmer must take care to deregister each object when reaching its end-of-life. Otherwise, a memory leak occurs as the Guava EventBus will hold the object’s reference indefinitely even after the programmer intended the object to be garbage-collected. If weak references were held by the bus, then terminating objects could proceed to garbage collection while the bus detected and deregistered any such disappeared (garbage-collected) objects.

Also, a minor issue, Guava EventBus supports asynchronous dispatch through a subclass rather than by default.

On the upside, we can expect Google’s team to thoroughly test and debug their work.

Read this article showing usage of Guava EventBus.

MBassador & Mycila


A couple years ago a pair of open-source event bus projects energetically burst upon the Java scene:
Both of these projects support weak references and async dispatch.

SimpleBus & EventBus


The inventor of MBassador wrote a comparison of a few older Java-based event bus projects (no mention of Mycila). His more modern library is reportedly much faster and uses less memory than its predecessors including Guava EventBus.

The other predecessors include:
  • SimpleBus
  • EventBus by Michael Bushe (apparently defunct)

GreenRobot EventBus


Recently I ran across GreenRobot EventBus project, a publish/subscribe event bus optimized for Android. I have not yet tried it.

Caveat: As of 2015-02, this library does not use weak references. This open issue # 57 requests such a feature. The main developer seems to be in favor. But not yet implemented.