Wednesday, July 29, 2009

Hello!

Greetings! This blog is a collection of guides and technical notes for doing various things, mostly in Ubuntu Linux. Here is a list the entries I find myself going back to often:

Ubuntu
Ubuntu Introduction
Installation scripts

Editors:
Installing Eclipse
Emacs (and SLIME with Clojure)
Vim

Java:
Installing Glassfish
Getting Started with Java Persistence API
R and Java

Flex:
Learning Flex
Flexbuilder in Linux
Flex, WebServices, Glassfish, Eclipse

Clojure:
Learning Clojure (and Emacs with SLIME)
MVC in Clojure
OpenGL in Clojure
3D Grapher in Clojure (using OpenGL)

LaTeX:
Getting Started with LaTeX
Pseudocode
LaTeX in VIM
LaTeX in Emacs

Graphics:
Installing Nvidia Drivers
OpenGL in Eclipse
OpenGL Cylinders and Spheres with inside test
Getting Started with CUDA in Ubuntu
CUDA in VIM
CUDA in Eclipse

Wordpress:
Installing Wordpress
Set up Email notifications

Unix:
Recursive word count
String replacement across many files
batch rename
delete all but a given type of file
remove all .svn directories
Redirect all output to a black hole

Utilities:
zipping and unzipping
using SVN (version control) command line client
Set the desktop background from the command line
Setting Up Synergy (cross-computer keyboard and mouse sharing)
NVidia Dual Monitor setup
Turn off the system beep and ALL system sounds
Code to HTML

All code and text on this blog is in the public domain, free to use and modify with no restrictions whatsoever.

Enjoy!

--Curran

Tuesday, July 28, 2009

Remove all .svn directories

Recursively removes all those pesky .svn directories in your tree:
find|grep [.]svn$|xargs rm -r -f

Sweet LaTeX development setup

Here's how I like to work with LaTeX these days: Linux terminal, Emacs, and Okular.

Open terminal, go to directory with .tex file (here I'll use all.tex as a sample file).

#create all.dvi
latex all

#open an auto-updating viewer in the background with messages stifled
okular all.dvi &> /dev/null &

#use Emacs as the editor
emacs -nw all.tex

#ctrl-z to put Emacs in background, then
#compile latex, and already open Okular automatically refreshes
latex all

#put emacs in foreground to edit further
fg

#from now on, to compile and view:
  • edit
  • ctrl+x s ! - save all in Emacs
  • ctrl+z - hide emacs
  • up arrow twice, enter - compile latex (execute latex all)
  • alt+tab - focus to Okular for viewing
  • alt+tab - focus to terminal
  • fg - show emacs
  • repeat
It gets really fast with a few repetitions.

Alternatively, one could map the compile command to a keystroke in Emacs, but I prefer a regular old terminal because of the great interactive error messages from LaTeX.

Links:
Running Shell Commands from Emacs

Unix redirection to black hole

I wanted to stifle Okular's annoying messages, so I learned how to redirect to a black hole:

okular > /dev/null

..but that only redirects stdout, and stderr still goes to the terminal. So, I learned how to redirect stderr to a black hole:

okular >& /dev/null

..but not stdout still goes to the terminal. Here's how to redirect both at once:

okular >& /dev/null

and put the application in the background:

okular >& /dev/null &

Another short but sweet unix success story.

Monday, June 8, 2009

Installation Scripts

I have organized some scripts for automating installation and configuration of things I end up doing every time I install Ubuntu. I use a BitBucket repository to store the scripts. Here they are:

#Common Things:
#install LaTeX, SVN
sudo apt-get install texlive subversion

#install and configure emacs and vim, kill the system beep
wget http://bitbucket.org/curran/ubuntuautomation/raw/c896a3c66d2f/fix_ubuntu.sh && sh ./fix_ubuntu.sh

#install eclipse
wget http://bitbucket.org/curran/ubuntuautomation/raw/c896a3c66d2f/install_eclipse.sh && ./install_eclipse.sh

#install Clojure and Clojure-SLIME
wget http://bitbucket.org/curran/ubuntuautomation/raw/1b06abf276e6/install_clojure.sh && sh ./install_clojure.sh

#Not-so-common Things:
#install glassfish
wget http://bitbucket.org/curran/ubuntuautomation/raw/c896a3c66d2f/install_glassfish_v2_1.sh && sh ./install_glassfish_v2_1.sh


To install everything at once:
wget http://bitbucket.org/curran/ubuntuautomation/raw/abb8f7116cbd/install_all.sh
#perhaps remove the things you don't want from the script...
sh ./install_all.sh

Wednesday, June 3, 2009

Command Line SVN Client

I've decided to learn the svn command line client. It turns out the svn command line is not that bad and complicated after all. Here are what I've gathered as the essentials:

to check out:
svn checkout [svn url]

to add a file to the repository (this is NOT comitting, so after "add"ing a file, it's not actually copied into the repository, it's just marked for inclusion in the next commit):
svn add [filename]

In SVN, when you add a new file, you need to "add" it to SVN, then "commit" it - two separate steps. It becomes tedious and error prone to find which files have been newly created and execute "svn add ..." for each one. Here's how you can ensure that all new files under the current directory are added:
svn add * --force

to commit all changed files in the current directory (to actually submit them to the repository or update them - note that the files must first be "add"ed):
svn commit -m "your comment here"

To remove a file from the repository, first delete it on your system, then execute:
svn delete [filename]

The comments you (and anyone else) add with -m "your comment here" are recorded in the SVN commit history. To view the comment history:
svn log | head -n 30

This uses the "head" unix utility to show only the first 30 lines of the output of "svn log", which shows the most recent 7 or 8 comments. "svn log" alone will spew out all comments ever written.

Daily use:

#update from the repository
svn up

#if you have local changes you want to discard, do the following:
#revert all, recursively, to the last update
svn revert -R ./
#do a fresh update
svn up

#to add a new file to svn
svn add newfile

#to remove a file
svn rm oldfile

#to move a file
svn mv oldfile newfile

#to commit
svn commit -m "your comment here"

SVN Cheat Sheet
Subversion client for Ubuntu: anything like TortoiseSVN?
SVN: Examining History

Wednesday, May 20, 2009

Linux Frustrations

I've been getting frustrated lately by Linux, I'm going to vent.

Seq24 (the sequencer) sucks
Seq24, a sequencing program, is broken out of the box in Ubuntu Studio. Why is this? Do the Ubuntu Studio folks to any testing before they release? I ranted with error messages on this forum and this bug report about seq24 - the package is broken, the web site download page is out of date, and the real latest code also crashes and doesn't connect to JACK, the audio server used by many Linux DAWs and synths.

Kile (the LaTeX IDE) sucks
Now I am trying to use Kile for LaTeX editing. It's totally hosed, completely crap compared to older versions. Here are the problems:
  • By default the lines don't wrap. Whats up with this? Doesn't just about EVERY SINGLE PERSON editing a LaTeX document want word wrap? Word wrap should definitely be on by default. Why not?
  • The menus Compile, Convert, View, and Other (under Build) - the ones used to BUILD AND VIEW LATEX, which is the WHOLE POINT of using the program - are empty, even though I have LaTeX and Okular etc. installed and can compile and view LaTeX from the command line just fine.
Okular (the KDE PDF/document viewer) sucks
  • When I open a pdf in Okular, it has these two huge ass panels on the right, one with "Bookmarks", "Reviews", "Thumbnails" and "Contents" (which is blanked out, why is that even there? that makes no sense whatsoever and should be taken away unless it is needed for SOMETHING)
  • So, I go to get rid of this ridiculous huge panel thing that should be hidden by default because it makes my document too small to read the text - which is the WHOLE POINT OF MY OPENING THE DOCUMENT IN THE FIRST PLACE - and I look in the "View" menu, because the panel thing - which I have no idea what it's even called, because it's not labeled - is definitely something I am viewing right now. Well, it turns out to be under Settings -> Show Navigation Panel, who'd have guessed.
Conclusions and recommendations to people who work with the stuff:

Seq24
  • @Ubuntu: Update the Ubuntu package to the latest version
  • @seq24: fix the crash when I click "tools" and have it connect to Jack out of the box
Kile
  • @Kile: Word wrap should be on by default.
  • @Kile: Kile should be able to build and view LaTeX documents out of the box.
  • @Ubuntu: The Kile package should be tested before releasing
Okular
  • @KDE/Okular: The navigation panel should be hidden by default - I can scroll just fine, thanks, without it.
  • @KDE/Okular: The navigation panel should be labeled "Navigation Panel" so I know what to look for when I want to close it.
  • @KDE/Okular: Better yet, it should have a little X in the upper right corner so I could just close it, the real estate lost wouldn't hurt anybody.

Thanks for listening. I'd appreciate it if anyone told me which specific procedures to go through to get these changes made, or if some specific log files or error details would be useful (I'll post them here).

If I have some time I'd like to help in fixing these annoyances. They give Linux a bad name.

Thursday, May 14, 2009

3D Grapher in Clojure

LiquidMath

GitHub repository

Curran Kelleher
May 13, 2009

Overview

LiquidMath is a 3D graphing calculator. It graphs implicit parametric equations, where (x,y,z) = f(u,v). Functions are input as Lisp code in the text box, and the surface is displayed as a freely rotatable 3D object. There is much room for improvement, I plan to continue developing this project.

Screenshot


Technology

LiquidMath is written in Clojure, a modern Lisp variant which compiles to Java bytecode. Java's Swing API is used for the GUI. OpenGL is used for 3D rendering, accessed via the Java OpenGL (JOGL) library. OpenGL Display Lists are used to achieve smooth rotation interaction.

Innovation

LiquidMath combines the dynamic nature of Lisp, the beauty of math, and the interactivity of modern graphics to deliver an effective educational tool for gaining insight into the nature of parametric surfaces. Conventionally, courses which explore 3D surfaces such as calculus III use only static diagrams. LiquidMath could be used by instructors during class, or by students when doing assignments.

Technology Used Block Diagram

LiquidMath is designed around the model-view-controller pattern, in which the model is the data representing salient application state, the view is the gui definition, and the controller sets up communication between the view and model. The view contains the text box and graphics panel. The text box updates the model via a listener added by the controller. The graphics panel is responsible for responding to changes in the model by generating and compiling code from the newly entered function string, then re-rendering the surface into the display list.

Additional Remarks

The full source code is posted here (public domain, feel free to use, copy, etc):

Here are some additional works that came out of this project:

The following are discussions on the Clojure mailing list:

Saturday, May 9, 2009

Visualization System Ideas

I just had an ! idea ! for a web-based visualization system architecture which would support selection across visualizations, collaborative visualization, and massive data sets.

The idea is that a url-accessible entity will contain a stateful resource which can be interacted with OpenGL-style via bunches of function calls (in URL requests). Some of the functions would be as follows:
  • Give me a session ID
    arguments:
    return value: sessionID
    side effect: initialize the session on the server side, make it usable
  • Load a data set into my session
    arguments: sessionID, pointer to distributed data set resource
    return value:
    side effect: loads the given data set pointer into the session, makes it usable
  • Create a visualization
    arguments: sessionID, visualization type
    return value: visualizationID
    side effect: load a visualization instance of the specified type, which uses the currently loaded data set, and can be referred to by the returned visualization ID
  • Set visualization parameters
    arguments: sessionID, visualizationID, parameter map
    return value:
    side effect: set the values of the specified visualization instance to the values of the given visualization-type-specific parameter map, which may contain values like which data rows/columns to visualize in which way, or which color map to use.
  • Set selection query
    arguments: data set query which can deduce a set of selected records.
    return value:
    side effect:
  • Set selection polygon
    arguments: sessionID, visualizationID, width, height, and a polygon (all in rendered-visualization-image-pixel-coordinates)
    return value:
    side effect: calls "Set selection query" with a query which derives the set of records that lie inside the specified polygon in the specified rendered visualization instance.
Until now, there's no heavy lifting whatsoever necessary. Here are the compute-intensive tasks:
  • Render visualization
    arguments: sessionID, visualizationID, width, height
    return value: an image of the rendered visualization (using the current data set of the session, representing visually the current selection, and the current parameters of the specified visualization instance), with the specified (width, height) pixel dimensions
    side effect: none, or perhaps do some setup which improves the speed of future renders.
There would also need to be some notification mechanism to signal the client to re-render each visualization when the selection changes, and when visualization parameters are modified (potentially by another user looking at the same visualization - that's the only thing I can see is necessary for collaboration)

Thats the idea, to be implemented to run on a cluster, perhaps in the cloud.

Thursday, May 7, 2009

Model-View-Controller GUI in Clojure

I've been experimenting with ways of coding GUIs which loosely follow the Model-View-Controller paradigm in Clojure, with some success. This post describes a simple working example - a gui that draws the text you type in the box.

Screenshot-GUI Test

The idea is to have a mutable object which encapsulates the application state (model), and gui code which reflects the state (view), and provides a way to change it (controller). In this case, the model is just a string, the view is the panel that draws the string, and the controller is the text field. When you type in the text field and hit enter, the model is changed, and the panel draws the new string.

Creating the Model

Clojure is incredibly well thought out in terms of mutability and concurrency, and provides several primitives for dealing with mutable objects. I used a Clojure ref object as the model, which wraps a string. The model is created at the top level, and pushed down as an argument to the GUI code (which conveniently closes over it, making it a persistently available pointer). The following code creates the model:
(ref "Hello MVC!")

Reading the Model
The text field is initialized with the value of the model with the following code:
...
(doto (JTextField.)
(.setText @model)
...
note - "@" serves to dereference a Clojure reference, yielding in this case the string wrapped by the model object.

The graphics panel reads and draws the model's every time it paints itself, with the following code:
(paint [g]
(doto g

...
(.drawString @model 20 40)
...

Mutating the Model

The model is mutated in the code of the ActionListener added to the text field:
(dosync (ref-set model new-text))
note - dosync performs a transaction, which is necessary when mutating Clojure references. (ref-set reference new-value) sets the value of the reference.

Listening to the Model
Clojure has this really cool "add-watch" feature where you can attach an update function to any mutable object! The function gets called every time the object changes. The following line attaches a watch function to the model which repaints the panel when the model changes:
(add-watch model "repaint" (fn [k r o n] (.repaint panel)))

The Code
Here is the code, totaling 74 lines. Any comments are appreciated.

If anyone knows how I can get nice syntax-highlighted HTML for this code, please let me know!
;A test program exploring how to structure GUI code in Clojure
;The GUI draws whatever you type in the text field nicely in the panel below.
;license: Public domain

(import '(javax.swing JFrame JLabel JTextField JButton JPanel)
'(java.awt.event ActionListener)
'(java.awt GridBagLayout GridBagConstraints Color Font RenderingHints))

(defn make-model [] (ref "Hello MVC!"))

(defn make-graphics-panel [model]
(let [panel
(proxy [JPanel] []
(JPanel [] (println "in constructor"))
(paint [g]
(doto g
;clear the background
(.setColor (. Color black))
(.fillRect 0 0 (.getWidth this) (.getHeight this))

;draw the text
(.setRenderingHint (. RenderingHints KEY_ANTIALIASING)
(. RenderingHints VALUE_ANTIALIAS_ON))
(.setFont (Font. "Serif" (. Font PLAIN) 40))
(.setColor (. Color white))
(.drawString @model 20 40))))]

;repaint when the model changes
(add-watch model "repaint" (fn [k r o n] (.repaint panel)))
panel))

(defn make-text-field [model]
(doto (JTextField.)
(.setText @model)
(.addActionListener
(proxy [ActionListener] []
(actionPerformed [e]
(let [new-text (.getActionCommand e)]
(dosync (ref-set model new-text))))))))

(defn make-gui-panel [model]
(defn make-text-field-constraints []
(let [c (GridBagConstraints.)]
(set! (.fill c) (. GridBagConstraints HORIZONTAL))
(set! (.weightx c) 1)
c))

(defn make-panel-constraints []
(let [c (GridBagConstraints.)]
(set! (.gridy c) 1)
(set! (.weighty c) 1)
(set! (.fill c) (. GridBagConstraints BOTH))
c))

(let [gridbag (GridBagLayout.)
text-field (make-text-field model)
panel (make-graphics-panel model)]
;set up the gridbag constraints
(doto gridbag
(.setConstraints text-field (make-text-field-constraints))
(.setConstraints panel (make-panel-constraints)))
;add the components to the panel and return it
(doto (JPanel.)
(.setLayout gridbag)
(.add text-field)
(.add panel))))

(defn show-in-frame [panel width height frame-title]
(doto (JFrame. frame-title)
(.add panel)
(.setSize width height)
(.setVisible true)))

(show-in-frame (make-gui-panel (make-model)) 300 110 "GUI Test")

Tuesday, April 14, 2009

The Tree Draws Well

I made the AST drawing program use a physics-like layout algorithm for drawing the abstract syntax tree of code parsed with my tiny lisp interpreter. Here's how it looks for fibbonacci:


the code

Thursday, April 9, 2009

Visualizing the Abstract Syntax Tree

I've decided to start on an abstract syntax tree visualization for my tiny Lisp interpreter. So far it just walks the tree and assigns incrementing X and Y locations based on depth and location in the list. The next step is to make a mini-physics simulation which minimizes the edge lengths and prevents overlaps. That should make much nicer looking trees.

I'm not sure if this is a standard way of visualizing Lisp abstract syntax trees - representing lists with a dot. I figured I can't put the function name at the node, because then it couldn't handle code that evaluates to a function that was returned from other code, like ((fn (x y z) (+ x y z)) 1 2 3)

Here's what it looks like to far:


It has overlap issues, here's what it does to fibbonacci:


the code

Wednesday, April 8, 2009

Factorial is possible!

I was able to add the minimum functionality necessary to implement factorial to my tiny Lisp interpreter.

Now the language has the following built-in functions: +,-,*,def,fn,and if. "if" is actually a function, because I made the function implementation responsible for evaluating its arguments, which are passed in as unevaluated abstract syntax trees. I'm not sure it that's correct, but it works for now.

Implementing all the primitives made me realize that those functions in Lisps take an arbitrary number of arguments. For example, in Clojure:
(<> true
but
(<> false

Implementing "if" involved clearly defining how booleans are represented. I decided that anything non-nil is true, and true is arbitrarily chosen as the number 1. This isn't very readable for printing out results, but it gets the job done. Maybe it would be a good idea to introduce a boolean type...not sure...maybe the just the notion of a "named constant"...

In any case, factorial works:
(def ! (fn (x) (if (< x 2) 1 (* x (! (- x 1))))))
(! 6) -> 720 (which is 6*5*4*3*2*1)

Sweet!

the code

Lambdas are here!

I was able to implement lambdas in my tiny Lisp interpreter, which required introducing local environments which delegate to their parents when lookup fails. I used "fn" instead of "lambda", like Clojure.

Now it can do stuff like:
(def double (fn (x) (+ x x)))
(double 100) -> 200

Now we're getting somewhere!

Next we'll need "if", then recursion will become possible.

the code

Progress in Tiny Lisp Interpreter

I have added a proper global environment to my tiny Lisp interpreter, introduced the notion of symbols, and implemented the def function. Now it can do stuff like:
(def a 8) -> 8
a -> 8
(def b (+ 5 6)) -> 11
b -> 11
(+ a b) -> 19

I wonder if, for a massively parallelized interpreter, it would be better to disallow redefinition of bindings. I would imagine it has benefits for distribution - if a symbols binding is guaranteed never to change, then the system could replicate and pass along the enclosing environment as fixed values when distribution across machines happens. Perhaps this is why Erlang is single assignment...

The next step is, hopefully, to implement lambda!

Here is the code for those interested.

Tuesday, April 7, 2009

A Tiny Lisp Interpreter

I ventured to write a simple Lisp interpreter in Java, and so far I've got a basic interpreter that is able to add numbers in less than 300 lines!

The only thing it can do now is parse and evaluate expressions like (+ 1 (+ (+ 1 2) 3 (+ 5 5))). Not very impressive, but it's a start. It has the essentials though: a recursive descent parser that transforms text into an abstract syntax tree (which is actually just (cons cells) filled with numbers and functions), and an eval/apply tree walker that runs the code.

It blows my mind that code is data in Lisps, and there is no syntax except parentheses and white space. Those aspects made writing the interpreter a lot easier than I expected. I found myself needing to write functional code in Java to make the thing work - for example, there is a tree walker that generates the code from the abstract syntax tree. That code was more natural to phrase functionally instead of object oriented-ly - x.toString() became toString(x), and suddenly the implementation became more straightforward.

Here is the code so far in case anyone is interested, (I hereby release it into the public domain!) I hope to eventually make a front end that visualizes code running in a simulated sea of parallel processors, in an effort to understand how I could implement such a system to run in an actual sea of processors.

What is Compute Intensive?

I'm trying to think of all the fields that could practically benefit from the ability to handle massive amounts of data, and massive amounts of computation. Please comment if you have more ideas!

Bioinformatics - useful for drug discovery and scientific understanding:
Genomics - vast amounts of sequence data
Proteomics - protein folding simulations need lots of compute power
Microarray Analysis - very large data sets are generated from microarray experiments, which need to be statistically analyzed, which requires heavy computing power.
Geospatial Information Systems - useful in understanding soceity and natural geographic phenomena - Data sets of geographically grounded indicators (think the Census) are very large, and progress over time. Statistical analysis of these data sets is very compute intensive
Computer Graphics:
Gaming - fun - graphics are compute intensive
Computer Vision - useful in manufacturing, robotics, understanding perception - compute intensive
Physics Simulations - advancing knowledge in physics - Compute Intensive
Weather Simulations - observing and predicting the weather - VERY data and compute intensive
Text mining - information aggregation and summarization, search - Data and compute intensive

I'm envisioning a computational system which assumes an infinite sea of processors (similar to the CUDA model of computation), and uses instead of a single stack, a branching stack, in which everything that can happen in parallel does hapen in parallel. I can see that such a system is implementable on GPUs with CUDA (or possibly OpenCL, I don't know much about that yet) by implementing a Lisp-like eval-apply loop which only acts on leaves of the stack tree (which can be compacted in log(n) time in parallel).

If the system can also be designed in such a way that it can orchestrate and evolve itself (its repetitive computation delegation decisions) over a cloud of machines with various compute facilities (both GPUs and *-core CPUs) with speed optimization as an emergent property, then it could change the world ... but only if people actually need it for something practical.

Could people actually benefit from such a system? Or is it just an academic pursuit?

Monday, April 6, 2009

Memoization - wtf?

This is the one of the coolest thing I have seen in a while. Try to grok this code:
(defn memoize [f]
(let [mem (atom {})]
(fn [& args]
(if-let [e (find @mem args)]
(val e)
(let [ret (apply f args)]
(swap! mem assoc args ret)
ret)))))

(defn fib [n]
(if (<= n 1)
n
(+ (fib (dec n)) (fib (- n 2)))))

(time (fib 35))
user=> "Elapsed time: 941.445 msecs"

(def fib (memoize fib))

(time (fib 35))

user=> "Elapsed time: 0.044 msecs"
What the heck!?

It wraps a function with a function that caches its return values for each signature it sees and returns the pre-baked cakes instead of baking the same cake over and over. Sweet! What a great idea!

Source: Clojure Atoms

Friday, April 3, 2009

OpenGL in Clojure

After much struggling I finally got a simple OpenGL example working in Clojure!

Here's a port of the JOGL example in Wikipedia to Clojure:
;This is a Clojure port of the JOGL example in Wikipedia
;Author: Curran Kelleher
;License: Public Domain
;dependencies: jogl.jar, gluegen-rt.jar

;for the REPL (use C-x C-e):
(comment
;these are the default paths of the jars in Ubuntu
(add-classpath "file:/usr/share/java/jogl.jar")
(add-classpath "file:/usr/share/java/gluegen-rt.jar")
)

(import '(java.awt Frame)
'(java.awt.event WindowListener WindowAdapter KeyListener KeyEvent)
'(javax.media.opengl GLCanvas GLEventListener GL GLAutoDrawable)
'(javax.media.opengl.glu GLU)
'(com.sun.opengl.util Animator))
(def rotateT 0)
(def glu (new GLU))
(def canvas (new GLCanvas))
(def frame (new Frame "Jogl 3D Shape/Rotation"))
(def animator (new Animator canvas))
(defn exit "Stops animation and closes the OpenGL frame." []
(.stop animator)
(.dispose frame))

(.addGLEventListener
canvas
(proxy [GLEventListener] []
(display
[#^GLAutoDrawable drawable]
(doto (.getGL drawable)
(.glClear (. GL GL_COLOR_BUFFER_BIT))
(.glClear (. GL GL_DEPTH_BUFFER_BIT))
(.glLoadIdentity)
(.glTranslatef 0 0 -5)

(.glRotatef rotateT 1 0 0)
(.glRotatef rotateT 0 1 0)
(.glRotatef rotateT 0 0 1)
(.glRotatef rotateT 0 1 0)

(.glBegin (. GL GL_TRIANGLES))

; Front
(.glColor3f 0 1 1)
(.glVertex3f 0 1 0)
(.glColor3f 0 0 1)
(.glVertex3f -1 -1 1)
(.glColor3f 0 0 0)
(.glVertex3f 1 -1 1)


; Right Side Facing Front
(.glColor3f 0 1 1)
(.glVertex3f 0 1 0)
(.glColor3f 0 0 1)
(.glVertex3f 1 -1 1)
(.glColor3f 0 0 0)
(.glVertex3f 0 -1 -1)

; Left Side Facing Front
(.glColor3f 0 1 1)
(.glVertex3f 0 1 0)
(.glColor3f 0 0 1)
(.glVertex3f 0 -1 -1)
(.glColor3f 0 0 0)
(.glVertex3f -1 -1 1)

;Bottom
(.glColor3f 0 0 0)
(.glVertex3f -1 -1 1)
(.glColor3f 0.1 0.1 0.1)
(.glVertex3f 1 -1 1)
(.glColor3f 0.2 0.2 0.2)
(.glVertex3f 0 -1 -1)

(.glEnd))
(def rotateT (+ 0.2 rotateT)))

(displayChanged [drawable m d])

(init
[#^GLAutoDrawable drawable]
(doto (.getGL drawable)
(.glShadeModel (. GL GL_SMOOTH))
(.glClearColor 0 0 0 0)
(.glClearDepth 1)
(.glEnable (. GL GL_DEPTH_TEST))
(.glDepthFunc (. GL GL_LEQUAL))
(.glHint (. GL GL_PERSPECTIVE_CORRECTION_HINT)
(. GL GL_NICEST)))
(.addKeyListener
drawable
(proxy [KeyListener] []
(keyPressed
[e]
(when (= (.getKeyCode e) (. KeyEvent VK_ESCAPE))
(exit))))))

(reshape
[#^GLAutoDrawable drawable x y w h]
(when (> h 0)
(let [gl (.getGL drawable)]
(.glMatrixMode gl (. GL GL_PROJECTION))
(.glLoadIdentity gl)
(.gluPerspective glu 50 (/ w h) 1 1000)
(.glMatrixMode gl (. GL GL_MODELVIEW))
(.glLoadIdentity gl))))))

(doto frame
(.add canvas)
(.setSize 640 480)
(.setUndecorated true)
(.setExtendedState (. Frame MAXIMIZED_BOTH))
(.addWindowListener
(proxy [WindowAdapter] []
(windowClosing [e] (exit))))
(.setVisible true))
(.start animator)
(.requestFocus canvas)


Here's a shell script that will run it:
#!/bin/sh
java -cp $CLOJURE_EXT/clojure.jar:/usr/share/java/jogl.jar:/usr/share/java/gluegen-rt.jar clojure.main joglExample.clj

The libraries can be installed in Ubuntu with
sudo apt-get install libjogl-java

Here's the refactored Java example from Wikipedia:
import javax.media.opengl.GL;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.glu.GLU;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.media.opengl.GLCanvas;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import com.sun.opengl.util.Animator;

public class joglExample implements GLEventListener, KeyListener {
float rotateT = 0.0f;
static GLU glu = new GLU();
static GLCanvas canvas = new GLCanvas();
static Frame frame = new Frame("Jogl 3D Shape/Rotation");
static Animator animator = new Animator(canvas);
public void display(GLAutoDrawable gLDrawable) {
final GL gl = gLDrawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -5.0f);

gl.glRotatef(rotateT, 1.0f, 0.0f, 0.0f);
gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);
gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f);
gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);

gl.glBegin(GL.GL_TRIANGLES);

// Front
gl.glColor3f(0.0f, 1.0f, 1.0f);
gl.glVertex3f(0.0f, 1.0f, 0.0f);
gl.glColor3f(0.0f, 0.0f, 1.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glColor3f(0.0f, 0.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);

// Right Side Facing Front
gl.glColor3f(0.0f, 1.0f, 1.0f);
gl.glVertex3f(0.0f, 1.0f, 0.0f);
gl.glColor3f(0.0f, 0.0f, 1.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glColor3f(0.0f, 0.0f, 0.0f);
gl.glVertex3f(0.0f, -1.0f, -1.0f);

// Left Side Facing Front
gl.glColor3f(0.0f, 1.0f, 1.0f);
gl.glVertex3f(0.0f, 1.0f, 0.0f);
gl.glColor3f(0.0f, 0.0f, 1.0f);
gl.glVertex3f(0.0f, -1.0f, -1.0f);
gl.glColor3f(0.0f, 0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);

// Bottom
gl.glColor3f(0.0f, 0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glColor3f(0.1f, 0.1f, 0.1f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glColor3f(0.2f, 0.2f, 0.2f);
gl.glVertex3f(0.0f, -1.0f, -1.0f);

gl.glEnd();

rotateT += 0.2f;
}

public void displayChanged(GLAutoDrawable gLDrawable,
boolean modeChanged, boolean deviceChanged) {
}

public void init(GLAutoDrawable gLDrawable) {
GL gl = gLDrawable.getGL();
gl.glShadeModel(GL.GL_SMOOTH);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClearDepth(1.0f);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_LEQUAL);
gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT,
GL.GL_NICEST);
gLDrawable.addKeyListener(this);
}

public void reshape(GLAutoDrawable gLDrawable, int x,
int y, int width, int height) {
GL gl = gLDrawable.getGL();
if(height <= 0) {
height = 1;
}
float h = (float)width / (float)height;
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(50.0f, h, 1.0, 1000.0);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
}

public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
exit();
}
}

public void keyReleased(KeyEvent e) {
}

public void keyTyped(KeyEvent e) {
}

public static void exit(){
animator.stop();
frame.dispose();
System.exit(0);
}

public static void main(String[] args) {
canvas.addGLEventListener(new joglExample());
frame.add(canvas);
frame.setSize(640, 480);
frame.setUndecorated(true);
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
exit();
}
});
frame.setVisible(true);
animator.start();
canvas.requestFocus();
}
}


Here's a shell script that will run it:
#!/bin/sh
javac -cp /usr/share/java/jogl.jar:/usr/share/java/gluegen-rt.jar joglExample.java
java -cp ./:/usr/share/java/jogl.jar:/usr/share/java/gluegen-rt.jar joglExample

Enjoy!

Links:
Gears demo in Clojure
Wikipedia JOGL demo

Wednesday, March 25, 2009

Learning Clojure and Emacs

I had an opportunity to attend the International Lisp Conference 2009. It was very interesting and inspiring. I learned that for all the greatness and age of Lisp, it is still a crufty and fragmented platform in practice.

However, lots of people believe that Clojure solves many of Lisps problems, and may be the key to the future of Lisp. Clojure is a modern dialect of Lisp that compiles to Java bytecode, cleans up much of Lisps cruft and antiquated naming, enables Java <-> Lisp interoperability, and has built-in support for concurrency.

After I expressed my frustrations with learning Lisp and Emacs, one guy at the conference said to me matter of factly "You're going to have to battle the language and the IDE at the same time. That's how one starts on the road to Lisp. Once you get past the initial hump though, I guarantee you'll never want to go back to Java. Once you get there, you should fill out the road to Lisp survey!"

There does seem to be something powerful lurking in Lisp, because there are endless testimonials (Beating the Averages by Paul Graham is particularly famous and well written) on how Lisp enabled lightning fast adaptive development, is fun to program, is amazingly powerfull, is elegant, beautiful, and so on. That said, I thought I'd give Clojure a try. Emacs seems to be hailed as the best Lisp IDE, so I'll try that too.

Here's the beginning (and perhaps end, only time will tell) of my modern day adventure on the road to Lisp: Clojure + Emacs + Ant + Ubuntu:

Setting Up Clojure and Emacs

#Install Java, Ant, Subversion, and Git.
sudo apt-get install openjdk-6-jdk ant subversion git-core emacs -y

#Run these simple setup scripts derived from these tutorials from Riddell: clojure slime
wget http://www.curransoft.com/code/setupClojure.sh wget http://www.curransoft.com/code/setupClojureSlime.sh sh setupClojure.sh
sh setupClojureSlime.sh

The contents of the scripts are as follows (just so you can see):
setupClojure.sh:
#!/bin/sh
# Adapted from http://riddell.us/tutorial/clojure/clojure.html
echo "Making ~/opt directory"
mkdir ~/opt
cd ~/opt
echo "Getting Clojure code from SVN..."
svn co http://clojure.googlecode.com/svn/trunk clojure
cd clojure
echo "Building Clojure..."
ant
mkdir ~/.clojure
cp clojure.jar ~/.clojure
cd ~/opt
echo "Getting Clojure-Contrib code from Git..."
git clone git://github.com/kevinoneill/clojure-contrib.git
cd clojure-contrib
echo "Building Clojure-Contrib"
ant -Dclojure.jar=../clojure/clojure.jar
cp *.jar ~/.clojure
echo "Setting up CLOJURE_EXT environment variable and "clj" alias
echo "export CLOJURE_EXT=~/.clojure
PATH=\$PATH:~/opt/clojure-contrib/launchers/bash
alias clj=clj-env-dir" >> ~/.bashrc
echo "Done."
setupClojureSlime.sh:
#!/bin/sh
# Adapted from http://riddell.us/tutorial/slime_swank/slime_swank.html
cd ~/opt
echo "Getting Clojure-Mode from GIT..."
git clone git://github.com/jochu/clojure-mode.git
echo "Getting Slime from GIT..."
git clone git://git.boinkor.net/slime.git
echo "Getting Slime from GIT..."
git clone git://github.com/jochu/swank-clojure.git
echo "Configuring Emacs (appending to ~/.emacs"
echo ";; clojure-mode
(add-to-list 'load-path \"~/opt/clojure-mode\")
(require 'clojure-mode)
;; swank-clojure
(add-to-list 'load-path \"~/opt/swank-clojure\")
(require 'swank-clojure-autoload)
(swank-clojure-config
(setq swank-clojure-jar-path \"~/.clojure/clojure.jar\")
(setq swank-clojure-extra-classpaths
(list \"~/.clojure/clojure-contrib.jar\")))
;; slime
(eval-after-load \"slime\"
'(progn (slime-setup '(slime-repl))))

(add-to-list 'load-path \"~/opt/slime\")
(require 'slime)
(slime-setup)">>$HOME/.emacs
echo "Done."

In Emacs:
M-x slime

It works! You should get a REPL (Read-eval-print loop) in which you can type
(+ 41 1) and get 42.

Learning Emacs
As for learning Emacs, here's what I learned:

emacs -nw starts the terminal version of emacs

To get to the built-in tutorial (which is awesome for getting started), open emacs, and hit C-h t (hit Control+h, then hit t). Here are the main points of the tutorial:
  • C-x means Control+x
  • M-x means Alt+x
  • C-x C-c closes emacs
  • C-v is page down
  • M-v is page up (Ironically, this collides with the very menu item which when clicked will solve the collision problem)
  • C-l centers vertically on the cursor
  • C-p is up arrow
  • C-n is down arrow
  • C-b is left arrow
  • C-f is right arrow
  • C-a is home (go to beginning of line)
  • C-e is end (go to end of line)
  • M-<> goes to end of file
  • C-u gives commands numeric arguments
  • (for example C-u 8 * types ******** and C-u 10 C-n goes down 10 lines)
  • M- is another way of giving commands numeric arguments
  • C-g cancels/stops/escapes things
  • C-x 1 closes all other windows (try C-h k C-f then C-x 1)
  • C-d is the delete key
  • C-k kills (deletes but copies) the rest of a line
  • C-spacebar sets a marker, and C-w kills text between the marker and the cursor
  • C-y pastes the killed text
  • M-y cycles in place through all sets of killed text (way cool! The clipboard is a stack!)
  • C-/ is undo (C-x u and C-_ are also). Redo is undo after do - Emacs has a very unique way of handling redo - once a sequence of undos is broken by doing something (typing a character for example), the undos become events which can themselves be undone, making them effectively redos. So there is only undo, but it can be used to undo undos (which is to do a redo).
  • C-x C-f opens ("finds") a file
  • C-x C-s saves a file
  • C-x C-b list buffers (remember C-x 1 to hide the list)
  • C-x s saves some buffers (prompts you)
  • C-z suspend
  • fg (in terminal) resume
  • M-x replace-string stringtofind replacement - replaces a string (repls autocompletes nicely)
  • C-s is search (C-s to go to next, enter to move cursor to search result, C-g to stop search)
  • C-r is backwards search
  • C-x 2 splits into two windows vertically
  • C-x 3 splits into two windows horizontally
  • C-x o go to the other window
  • C-x 4 C-f open file in new window
Really Learning Emacs
  • To replace commas with newlines:
    M-x replace-string ,C-q C-j
  • C-x 0 close window
  • Giving arguments to C-x o is useful for navigating more than 2 windows (Emacs manual on Windows)
  • Copy and Paste (from here):
    C-space set mark
    C-w cut text between mark and cursor
    M-w copy all text between mark and cursor
    C-y paste
  • C-x k Close buffer
  • M-x cd change working directory
  • You can record little scripts, called emacs macros (from emacs manual):
    C-x ( Start defining a keyboard macro (start-kbd-macro).
    C-x ) End the definition of a keyboard macro (end-kbd-macro).
    C-x e Execute the most recent keyboard macro (call-last-kbd-macro).
  • C-M-\ Autoformat/"indent region"/autoindent
  • C-j newline and tab
  • M-^ merge (join) lines (lots of Indentation tips from the emacs manual)
Learning SLIME(Superior Lisp Interaction Mode for Emacs)
Here is a summary of this excellent tutorial, with some modifications:
Start slime with M-x slime
You'll get a REPL - Read Eval Print Loop
Type 234, it will evaluate to 234
Type hello, you will get an error. To get out of SLDB (Slime Debugger), hit 0
M-p and M-n act like up and down arrows for browsing command history
Split Emacs into two vertical windows with C-x 2
In one window, use C-x C-f to open a new file called hello.clj
Buffer and window manipulation review:
  • C-x o: move the cursor to the "o"ther window.
  • C-x 1: Make there be only one window (the one with the cursor in it)
  • C-x 2: Split the current window vertically into two windows
  • C-x b: Switch the current window to a different buffer, whose name I will type. (Space does name completion.)
  • C-x C-b: Show a list of all the buffers (along with some other information like what Emacs mode each one is in, what file is loaded into each one, etc.). Moving the cursor over one and hitting enter loads that buffer into the current window.
Really Learning Slime
Adapted from this tutorial, the Slime Manual, this conversation

It seems nearly impossible to find reasonable documentation for how people actually use Slime! Very frustrating. It's either a huge manual or an isolated snippet. Here's what I've found. Start from a fresh Emacs and follow these steps to learn how to use Slime:
  • M-x slime this starts Slime and gives you a REPL
  • C-x 2 splits the screen in half
  • C-x C-f test.clj creates and opens the file test.clj
  • Paste the following code into test.clj (using Shift+insert)
    (import ;imports necessary just like in Java                                
    '(java.awt Graphics)
    '(javax.swing JPanel JFrame))
    (defn render [#^Graphics g] ;"#^" is an optional type hint to the compiler
    (doto g ;"doto" lets you call successive functions on an object
    (.drawString "Hello World!" 10 20)));draw "Hello World!" on the graphics passed in
    (def panel (proxy [JPanel] [] ;proxy creates anonymous subclasses
    (paint [g] (render g)))); this line overrides JPanel's paint method
    (def frame (doto (new JFrame);doto returns its first argument
    (.add panel);add the panel to the frame
    (.setBounds 100 100 100 60);set the dimensions of the frame
    (.setVisible true)));show the frame
  • C-c C-k compiles and runs the current buffer, which will pop up a window
  • Change "Hello World!" to something else
  • C-c C-c compile current top-level form (it blinks!)
  • Now resize the java window to trigger a repaint - it paints the new value
  • In the Repl (C-x C-o gets you there), enter
    (. frame setBounds 0 0 500 500)
    You'll see the frame change.
  • This is the Lisper's notion of "incremental development" or "live coding" - no rebuild is necessary, you can make changes live! Amazing!
  • Here's another example of creating a Java GUI:
    (doto (JFrame.)
    (.add
    (doto (JButton. "Click me!")
    (.addActionListener
    (proxy [ActionListener] []
    (actionPerformed [e] (println "Clicked!"))))))
    (.setBounds 400 400 200 200)
    (.setVisible true))
  • Println calls and compile errors go to the buffer *inferior-lisp*, so it's nice to have it open. If you put the cursor at the end it scrolls output for you as it comes.

Misc tips:
  • C-h b describes all available keybindings (very useful)
  • q hides notifications
  • C-x C-e evaluates the expression before the cursor (ONLY that expression)
Learning Basic Clojure The essentials of Lisp
Adapted from Structure and Interpretation of Computer Programs lecture by Hal Abelson
  • The essence of a language are its primitives, means of combination, and means of abstraction:
  • Basic primitives are numbers: 5 -> 5, 1.5 -> 1.5
  • Combination is parentheses-based: (+ 5 6) -> 11
  • Definitions are a means of abstraction: (def a 5), a -> 5
  • Functions are another means of abstraction:
    (defn square [x] (* x x))
    (square 5) -> 25
  • Functions can also be defined like this (fn is like lambda in Lisp):
    (def square (fn [x] (* x x)))
    defn... is "syntactic sugar" for def...fn... (they mean the same exact thing)
  • Conditional execution using "if" works as follows:
    (defn abs [x] (if (< x 0) (- x) x))
    Conditional execution using "cond" works as follows (cond works with an arbitrary number of conditional-result pairs):
    (defn abs [x] (cond (< x 0) (- x) (= x 0) 0 (> x 0) x))
Learning Clojure
This tutorial is awesome. Here are the key points:
  • important atoms: true, false, nil
  • Strings: "hello"
  • Lists: (list 1 2 3) is equivalent to '(1 2 3)
  • Keywords - like variables but with no bindings: :a :b :foo
  • Addition: (+ 3 3 3)
  • Vectors (like lists): [1 2 3] or (vector 1 2 3)
  • Maps (dictionaries): {"a" 1, "b" 2, "c" 3}
  • Map access: (get {"a" 1, "b" 2, "c" 3} "b") evaluates to 2 (commas are whitespace - they'rs not necessary but help readability)
  • Map access: ({"a" 1, "b" 2, "c" 3} "b") evaluates to 2
  • Definition (assignment): (def x 5) is like int x=5; in Java
  • Definition (assignment): (def my-list '(1 2 3)) is like int[] myList={1,2,3}; in Java
  • Defining functions: (defn election-year? [year] (zero? (rem year 4))) is like boolean electionYear(int year){return year%4==0;} in Java
  • Lambdas: (fn [x] (+ x 1)) creates a function that increments x
  • Lambdas: ((fn [x] (+ x 1)) 9) evaluates to 10
  • Documentation: (doc first) prints documentation for the function "first"
  • Documentation: (defn plus-one "Returns x+1" [x](+ x 1)) gives plus-one "Returns x+1" as a documentation string.
  • String contatenation: (str "Hello," " world!") evaluates to "Hello, world!"
  • If: (if (= 1 1) "yes" "no") is like 1==1?"yes":"no", and evaluates to "yes"
  • Do: (do (println "Hello.") (+ 2 2)) executes (println "Hello.") then (+ 2 2) and evaluates to 4. This is how you can do sequences of stuff.
  • When (a conditional version of do): (when true (println "Hello, world") "Yes") executes (println "Hello, world") and evaluates to "Yes"
  • Let: (let [x 2, y 8] (+ x y)) evaluates to 10. The let form creates a temporary var (x and y in this case), that can only be used inside the body of the let expression.
  • Java integration: (. (new java.util.Date) (toString)) evaluates to "Thu Mar 26 20:41:12 EST 2009"
  • import: (import '(java.io FileReader))
  • Constructor invocation: (new FileReader "source.txt")
    Syntactic sugar f: (FileReader. "source.txt")
  • For loop: (loop [i 0](when (<>
  • For loop: (dorun (for [i (range 0 5)] (println i)))
  • For loop: (doseq i (range 0 5) (println i))
  • Sequences (Very important concept, read more here):
    (seq [1 2 3]) creates a sequence from the vector [1 2 3]
    The following functions act on sequences: first, rest, cons
  • first (like car): (first '("one" "two" "three")) evaluates to "one"
  • rest (like cdr): (rest '("one" "two" "three")) evaluates to ("two" three")
  • cons: (cons 1 [2 3]) evaluates to (1 2 3)
Practical Clojure - Java Interop
Here's an illustrative Java GUI example, taken from here:
(import '(javax.swing JFrame JLabel JTextField JButton)
'(java.awt.event ActionListener)
'(java.awt GridLayout))
(defn celsius []
(let [frame (JFrame. "Celsius Converter")
temp-text (JTextField.)
celsius-label (JLabel. "Celsius")
convert-button (JButton. "Convert")
fahrenheit-label (JLabel. "Fahrenheit")]
(.addActionListener convert-button
(proxy [ActionListener] []
(actionPerformed [evt]
(let [c (Double/parseDouble (.getText temp-text))]
(.setText fahrenheit-label
(str (+ 32 (* 1.8 c)) " Fahrenheit"))))))
(doto frame
(.setLayout (GridLayout. 2 2 3 3))
(.add temp-text)
(.add celsius-label)
(.add convert-button)
(.add fahrenheit-label)
(.setSize 300 80)
(.setVisible true))))
(celsius)

Conclusion
Well, I guess I'm on the road to Lisp. So far I'm sold - there are lots of great ideas in the Lisp paradigm, and Clojure seems very elegant and usable. Livecoding was totally alien to me before, and it seems like a much better - and more fun! - way of doing things than the conventional edit-compile-run cycle.

It's still a mystery how object orientation and multithreading are accomplished in Clojure, but it seems like those things are also doable. Macros are also still a mystery to me - people seem to think they are some kind of holy grail. So, though I've made some progress, there's still lots to look forward to!

Links:
Clojure
Clojure with Emacs and Slime/Swank on Ubuntu
Clojure Wikibook - Programming/Getting Started
Emacs for vi users
Emacs replace with Newline
Slime Tutorial
Slime Manual (PDF)
Clojure Tutorial for Non-Lispers
Clojure Web Server (in less than 100 lines)
20 Days of Clojure

concurrency talk by Rich Hickey - great overview of the hard concurrency problems that Clojure solves.

Saturday, February 28, 2009

Getting Started with JPA

JPA, the Java Persistence API, is the current standard technology for object-relational mapping in Java (mapping Java objects to relational databases and back). This guide walks through how to create a Web Service in Glassfish which uses JPA to interact with a local MySQL database, using Eclipse as the development environment.

Ingredients:
Ubuntu Linux 8.10
Glassfish 2.1 (how to install)
Eclipse Ganymede (Java EE version)
MySQL 5 (install with sudo apt-get install mysql-server mysql-client)

Steps:
Create a new project:
In Eclipse: New -> Project -> Dynamic Web Project -> name: "JPA_Test", Target Runtime: "GlassFish v2 Java EE 5" (if Glassfish is not listed, click New->Download additional Server Adapters->choose Glassfish ...) -> Finish

Create the following classes:
package test;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Customer {
private String name;
private int id;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}

and
package test;

import javax.annotation.Resource;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.transaction.UserTransaction;

@WebService
public class Test {

@PersistenceUnit
private EntityManagerFactory emf;

@Resource
private UserTransaction utx;

public boolean putCustomer(String name, int id) {
EntityManager em = emf.createEntityManager();
try {
utx.begin();

Customer c = new Customer();
c.setId(id);
c.setName(name);

em.persist(c);
utx.commit();
em.close();
} catch (Exception e) {
em.close();
e.printStackTrace();
return false;
}
return true;
}
public String getCustomerName(int id) {
EntityManager em = emf.createEntityManager();
Customer c = em.find(Customer.class, id);
return c.getName();
}
}

Under src/META-INF, put a file called persistence.xml with the following contents:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="pu1" transaction-type="RESOURCE_LOCAL">
<class>test.Customer</class>
<properties>
<property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="toplink.jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
<property name="toplink.jdbc.user" value="root"/>
<property name="toplink.jdbc.password" value="root"/>
<property name="toplink.logging.level" value="INFO"/>
<property name="toplink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>


Create the MySQL database to use:
#Start the MySQL Terminal:
mysql -u root -p
#create a database called test
mysql> CREATE DATABASE test;

Launch it:
In Eclipse: Right click on project -> Run As -> Run on Server -> Choose Glassfish as the server -> Finish

Test it:
Go to http://localhost:4848/ -> log in -> Web Services -> choose the "Test" web service -> click the "Test" button -> Enter some test info, like "Jack" as arg0 and "0" as arg2 -> click the "putCustomer" button -> see "True" if success, False or an exception if not.

If it doesn't work, the Glassfish Log Viewer tab in Eclipse is very useful.

Good luck!

Common Errors:
javax.xml.ws.soap.SOAPFaultException: Object: .... is not a known entity type. at ...
This means that you tried to use a class with JPA that you didn't declare in your persistence.xml. Sometimes this happens even if you did declare the type, and often a restart of the server will fix it (I hate server bugs like that).

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near...
This may mean that you are using a SQL keyword as a class or property name. Avoid all SQL keywords, like "value" or "column".

Sources:
Great tutorial by Sahoo
MySQL tips
JPA tutorial for NetBeans
Persistence example from Glassfish

Wednesday, January 21, 2009

Installing GlassFish

Cooking up some GlassFish in Linux (from here and here)

I put all these commands in a shell script, which can be executed with:
wget http://bitbucket.org/curran/ubuntuautomation/raw/21ad83206eca/install_glassfish_v2_1.sh && sh ./install_glassfish_v2_1.sh

Installing Glassfish:
(mkdir ~/opt)
cd ~/opt
# download glassfish
wget http://java.net/download/javaee5/v2ur2/promoted/Linux/glassfish-installer-v2ur2-b04-linux.jar
# unzip glassfish
java -Xmx256m -jar glassfish-installer-v2ur2-b04-linux.jar
cd glassfish/
# give the bin directory execute permissions
chmod -R +x lib/ant/bin
# run the setup
lib/ant/bin/ant -f setup.xml
# add the glassfish bin directory to the PATH environment veriable
echo "PATH=\$PATH:$HOME/opt/glassfish/bin export PATH" >> ~/.bashrc

Using Glassfish

# to start the server, restart the terminal (for PATH to update) then run
asadmin start-domain domain1
# to verify glassfish is working, go to http://localhost:8080/
# the admin GUI, which we'll use later, is at http://localhost:4848/
# user: admin pass: adminadmin

# to stop the server
asadmin stop-domain domain1

#To deploy a WAR file, put it in the autodeploy directory.
mv yourwarfile.war ~/opt/glassfish/domains/domain1/autodeploy/

#To view the last 50 lines of the log file:
tail -n 50 ~/opt/glassfish/domains/domain1/logs/server.log

Notes on MySQL and Flash access
# if you want MySQL support, put the lib in the right place:

wget http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.7.zip/from/http://mysql.mirror.redwire.net/
unzip mysql-connector-java-5.1.7.zip
mv mysql-connector-java-5.1.7/mysql-connector-java-5.1.7-bin.jar ~/opt/glassfish/lib/


# if you want to access a web service through a flash-based client, you need a permissive crossdomain.xml file placed in the domain root that looks something like this:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*"/>
<site-control permitted-cross-domain-policies="all" />
<allow-http-request-headers-from domain="*" headers="SOAPAction"/>
</cross-domain-policy>



Using the Ubuntu Package
On second thought I went back and tried using the Ubuntu package. Here are some tidbits of insight, though I eventually gave up on it.

This useful command finds all files and directories with "glassfish" in them:
sudo find / -name '*glassfish*'

Here are the important locations:

asadmin: /usr/share/glassfishv2/bin/asadmin
autodeploy directory: /var/lib/glassfishv2/domains/domain1/autodeploy
log file : /var/lib/glassfishv2/domains/domain1/logs

To (try to) deploy a WAR file, put it in the autodeploy directory.

To view the last 100 lines of the log file:
tail -n 100 /var/lib/glassfishv2/domains/domain1/logs/server.log

Again I gave up on the Ubuntu package. There is just too much wrong with it:
  • The asadmin command doesn't work!
  • The directories are exploded into two locations, I don't get that at all.
  • Root permissions seems necessary to manipulate glassfish, this seems wrong.
  • Somehow when I deployed a WAR with a web service in it, the web service doesn't actually deploy. Very frustrating.

Enjoy!

Flex Builder in Linux

Here's how to get Flex Builder working in Linux.

(mkdir ~/
opt)
cd ~/opt

mkdir flex
cd flex
# download eclipse (3.3 because newer versions of Eclipse break Flex Builder)
http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/europa/winter/eclipse-java-europa-winter-linux-gtk.tar.gz
# install eclipse
gunzip < eclipse-java-europa-winter-linux-gtk.tar.gz | tar xvf -
# create a "flexbuilder" launcher that points to this Eclipse
sudo sh -c 'echo "#!/bin/sh \n export MOZILLA_FIVE_HOME=\"/usr/lib/mozilla/\"
\n export ECLIPSE_HOME=\"\$HOME/opt/flex/eclipse\" \n \$ECLIPSE_HOME/eclipse \$*" > /bin/flexbuilder'
sudo chmod +x /bin/flexbuilder

#to increase memory (sometimes this is a problem), add the following to the eclipse command in the launch script:
#-vmargs -Xms128m -Xmx1024m -XX:MaxPermSize=128m

#!/bin/sh
export MOZILLA_FIVE_HOME="/usr/lib/mozilla/"

export ECLIPSE_HOME="$HOME/opt/flex/eclipse"
$ECLIPSE_HOME/eclipse -vmargs -Xms128m -Xmx1024m -XX:MaxPermSize=128m$*


# download flex builder
wget http://download.macromedia.com/pub/labs/flex/flexbuilder_linux/flexbuilder_linux_install_a4_081408.bin

# install flex builder
chmod +x flexbuilder_linux_install_a4_081408.bin
./flexbuilder_linux_install_a4_081408.bin
# under "Where Would You Like Flex Builder Installed?", set it to
/home/yourusername/opt/flex/flexbuilder
# under "Please Choose an Existing Eclipse Folder" set it to
/home/yourusername/opt/flex/eclipse

Alt+F2 -> type "flexbuilder" to launch.

I would advise to keep separate workspaces for Flex and Java projects, because I've seen some funky behavior that indicates the Flex Builder plugin interferes with some Java features.

Lets try it out:
In Eclipse -> New -> Flex Project -> give a name -> Finish

Paste the following:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Label text="Hello Flex in Linux!"/>
</mx:Application>
F11 to run, it should pop up in Firefox.

Enjoy!

Monday, January 19, 2009

Flex, WebServices, Glassfish, Eclipse

1/20/2009

I was able to get a Flex client to invoke my first Web Service. I found that on the server side, a Web Service is trivial to code and deploy in a GlassFish server from Eclipse - a welcome relief from the complex BlazeDS configurations we've been dealing with. To make an existing class into a Web Service, only a @WebService annotation is needed. On the client side, the invoking code is pretty straightforward - just setting up a few listeners for response and faults. I observed that the Web Service call time (from a client on the same local network as the server, but a different machine) consistently has a pretty even distribution between 15 and 65 milliseconds.

This guide details steps in Ubuntu Linux for creating an end to end system with a Flex web GUI which invokes a Web Service in a Glassfish server. The steps are as follows, assuming a fresh Ubuntu:
  1. Install OpenJDK, Eclipse, and GlassFish
  2. Configure Eclipse for GlassFish
  3. Write, deploy, and test an "Echo" Web Service
  4. Install FlexBuilder Linux Alpha
  5. Write the "Echo" client
Install OpenJDK, Eclipse, and GlassFish

Install OpenJDK and Eclipse

Install GlassFish

Configure Eclipse for GlassFish

In Eclipse:
New -> Project -> Web -> Dynamic Web Project -> Next ->
under "Target Runtime" -> New... -> click "download additional server adapters" ->
select "GlassFish Java EE 5 Server" -> Next -> accept the terms, Finish -> OK -> Yes, restart now

New -> Dynamic Web Project -> Next ->
Name:EchoService
Make sure "Target Runtime" is set to "GlassFish v2 Java EE 5"
-> Finish

Right click EchoService/WebContent/index.jsp -> Run As -> Run on Server -> localhost GlassFish should be automatically selected, Finish
In the console, you'll be prompted for the admin username and password - enter user: admin, pass:adminadmin

If all goes well you should see an emphatic Hello World!

Write, deploy, and test an "Echo" Web Service

In the EchoService project -> New -> Class -> Name:Echo, Package:echo -> Finish
Paste the following:
package echo;
import javax.jws.WebService;

@WebService
public class Echo {
public String echo(String input) {
return input;
}
}
The only thing you need to do to write a web service is to add the @WebService annotation.

Right click Echo.java -> Run As -> Run on Server -> Finish

Eclipse will display an error page at "http://localhost:8080/EchoService/WEB-INF/classes/echo/Echo.java", but thats fine, because that's not what we're trying to accomplish.

To see the service, use the GlassFish admin GUI
Go to http://localhost:4848/ user: admin pass: adminadmin
On the left panel, click "Web Services" -> Echo -> Test ->
follow the http link (http://localhost:8080//EchoService/EchoService?Tester)
Enter "Hello World", then you should see the SOAP messages:

SOAP Request:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header/>
<S:Body>
<ns2:echo xmlns:ns2="http://echo/">
<arg0>Hello World!</arg0>
</ns2:echo>
</S:Body>
</S:Envelope>

SOAP Response:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:echoResponse xmlns:ns2="http://echo/">
<return>Hello World!</return>
</ns2:echoResponse>
</S:Body>
</S:Envelope>

Install Flex Builder

Write the "Echo" client
Create an EchoService Flex Client (sources: here and here and here (source code), Flex docs were also useful)
The URL of your WSDL file is at http://localhost:8080//EchoService/EchoService?WSDL

The following MXML code defines a simple GUI which calls the EchoService
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;

private var startTime:int;
private var endTime:int;

private function button_click():void {
webService.echo.send(textInput.text);
startTime = getTimer();
timeLabel.text = "";
}

private function echo_result(evt:ResultEvent):void {
resultLabel.text = "Result: "+evt.result.toString()
calcTime();
}

private function echo_fault(evt:FaultEvent):void {
Alert.show(evt.type);
calcTime();
}

private function calcTime():void {
endTime = getTimer();
timeLabel.text = "Time: " + (endTime - startTime) + "ms";
}
]]>
</mx:Script>

<mx:WebService id="webService"
<!-- replace this ip address with your own -->
wsdl="http://129.63.16.175:8080//EchoService//EchoService?WSDL">
<mx:operation name="echo"
resultFormat="object"
result="echo_result(event);"
fault="echo_fault(event);">
</mx:operation>
</mx:WebService>

<mx:Button id="button" label="Call service" click="button_click();" />
<mx:Label text="input:" />
<mx:TextInput id="textInput" text="Hello Flex!"/>
<mx:Label id="timeLabel" />
<mx:Label id="resultLabel" />
</mx:Application>

Replace the ip of the web service with "localhost" or your server ip, which you can find by executing
ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' |cut -d: -f2 | awk '{ print $1}'

Alternatively, you could set up the web service in ActionScript as opposed to MXML:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.rpc.soap.WebService;
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;

private var startTime:int;
private var endTime:int;
private var webService:WebService;

private function init():void{
webService = new WebService();
//replace this ip address with your own
webService.wsdl = "http://129.63.16.175:8080//EchoService//EchoService?WSDL"
webService.echo.resultFormat = "object"
webService.echo.addEventListener("result", echo_result);
webService.echo.addEventListener("fault", echo_fault);
webService.loadWSDL();
}

private function button_click():void {
webService.echo.send(textInput.text);
startTime = getTimer();
timeLabel.text = "";
}

private function echo_result(evt:ResultEvent):void {
resultLabel.text = "Result: "+evt.result.toString()
calcTime();
}

private function echo_fault(evt:FaultEvent):void {
Alert.show(evt.type);
calcTime();
}

private function calcTime():void {
endTime = getTimer();
timeLabel.text = "Time: " + (endTime - startTime) + "ms";
}
]]>
</mx:Script>

<mx:Button id="button" label="Call service" click="button_click();" />
<mx:Label text="input:" />
<mx:TextInput id="textInput" text="Hello Flex!"/>
<mx:Label id="timeLabel" />
<mx:Label id="resultLabel" />
</mx:Application>

Notes:

Build Failing due to Constructor issue
I was confused for a while about this error:
CLI171 Command deploydir failed : Deploying application in domain failed; Deployment Error -- Exception occured in the wsgen process javax.xml.ws.WebServiceException: Unable to create JAXBContext

BUILD FAILED
/home/curran/workspace/.metadata/.plugins/org.eclipse.jst.server.generic.core/serverdef/sunappsrv-ant.xml:203: The following error occurred while executing this line:
/home/curran/workspace/.metadata/.plugins/org.eclipse.jst.server.generic.core/serverdef/sunappsrv-ant.xml:119: exec returned: 1

I realized by reading the log file and reading this that the reason is because the exception type my service threw didn't have a no-argument constructor, which is apparently a requisite property of objects you send over the wire FROM a seb service.

Tracing Server-side Exceptions
they are appended to the log file at ~/opt/glassfish/domains/domain1/logs/server.log

To see the latest exceptions:
cat ~/opt/glassfish/domains/domain1/logs/server.log

Adding JARS to the server code dependency
put the jars you need into WebContent/WEB_INF/lib of your project

Enjoy!

Sunday, January 18, 2009

SOA in Eclipse Links

This Presentation (Part 1, Part 2) about the Eclipse WTP and SOA looks really useful.

Here's some raw incoherent notes for setup of Eclipse, OpenDJK, and Tomcat in Ubuntu 8.10.

Install OpenJDK and Eclipse

# Install Tomcat manually. Don't use the Ubuntu tomcat6 package, because it spreads tomcat across the filesystem, making it difficult to configure Eclipse.
# Download tomcat
cd ~/opt
wget http://www.ip97.com/apache.org/tomcat/tomcat-6/v6.0.18/bin/apache-tomcat-6.0.18.tar.gz
tar -zxvf apache-tomcat-6.0.18.tar.gz
# Start the server
~/opt/apache-tomcat-6.0.18/bin/startup.sh
#Go to http://localhost:8080/ to test
#This is the command to shutdown
~/opt/apache-tomcat-6.0.18/bin/shutdown.sh

Configure the Tomcat runtime in Eclipse:
In Eclipse, at Window -> Preferences -> Server -> Runtime Environment -> Add -> Apache Tomcat v6.0 -> Next -> set "Tomcat Installation Directory" to /opt -> Finish -> OK

Download Apache MyFaces libraries
cd ~/opt
wget http://mirror.its.uidaho.edu/pub/apache/myfaces/binaries/myfaces-core-1.2.5-bin.zip
unzip myfaces-core-1.2.5-bin.zip

# we need jet another jar that nobody mentioned
cd myfaces-core-1.2.5-bin/lib
wget http://download.java.net/maven/1/jstl/jars/jstl-1.2.jar

In Eclipse:
Project -> Properties -> Project Facets -> check "JavaServerFaces"
in the configuration, add ALL the jars in myfaces-core-1.2.5-bin/lib


Links:
Symbolic Links Advice
Tomcat in Ubuntu: apt-get vs manual install

Ubuntu Linux

I just installed the latest Ubuntu Linux, and thought I'd write a post for people new to Linux, who are curious but have kept their distance.

Ubuntu Linux is a complete free operating system - a competitor to Windows and Mac build with a philosophy of openness rather than a proprietary model. Linux alone (the "kernel") provides the bare essentials of an operating system, so people package it into readily usable forms - together with many open source applications and components. These are called distributions. Presently, Ubuntu is the most popular Linux distribution. It makes Linux simple for anyone to set up and use.


Getting Started

To install Ubuntu, download the latest version, burn it to a CD, and boot to the CD. You can try it out without installing or risking anything. This gives you an impression of the look and feel, and lets you try preinstalled applications, but is much slower than normal because it's running directly off the CD. You can install Ubuntu alongside an existing Windows installation, as a "dual boot" setup where you can choose when you start the computer which system to use. This is the default setting in the installer.

Once you have it installed, you can figure out what everything is by clicking or right clicking on it. You can customize the panels as much as you want - delete things, add things by dragging and dropping.


Installing Programs

One of the most different things from Windows is the way in which software is installed and managed. In Ubuntu, there is an entire body of software dedicated to installing, updating, and uninstalling applications in the form of "packages". This is called a package manager. Ubuntu's package manager is APT - Advanced Packaging Tool.

Ubuntu maintains a huge list of applications that can be automatically installed by the package manager. To install or remove programs, you can go to Applications -> Add/Remove, which lets you browse and search packages. To install or uninstall something, check or uncheck the box next to the package, then hit "Apply Changes." After a program is installed, it will appear in the "Applications" menu, filed in the right place.

Another program besides Ubuntu's "Add/Remove Programs" which lets you graphically manage packages is Synaptic - it also uses APT under the hood.


Standard Tools

Ubuntu comes preinstalled with open source alternatives for most tools most people use already:
  • Office -> OpenOffice
  • Photoshop -> GIMP
  • Internet Explorer, Safari -> Firefox
  • AIM (or any IM client) -> Pidgin
  • Skype -> Egika Softphone
  • Outlook -> Evolution Mail and Calendar

Keyboard Shortcuts

There are numerous standard keyboard shortcuts which make working in Ubuntu very efficient:
  • Alt+tab - switch between windows
  • Control+alt+ left/right arrow keys - switch between desktops
  • Alt+F4 - close the current window
  • F11 - fullscreen mode
  • F2 - rename a file

The Terminal


The terminal is very powerful. It allows you to enter commands to the operating system directly. Most stuff that you can do in Ubuntu with menus, windows, and buttons can probably also be done by entering a command in the terminal. It can be found under Applications -> Accessories -> Terminal.

One common use for the terminal is to install programs. For example, to install Wine, a system which lets you run most Windows programs in Linux, can be installed with one command:
sudo apt-get install wine

"sudo" gives you the power to change system files (you must manually enter your password - this is one reason why Linux is so secure)
"apt-get install" is the command to access the installation mechanism of Ubuntu's package manager APT (Advanced Packaging Tool)
"wine" is the name of the Ubuntu package you want APT to install. There are thousands of Ubuntu packages available.

You could also install any package from Applications -> Add/Remove (in fact, that program uses the apt-get install command), but once you know the package names of the programs you use often, you'll find it's faster to use the terminal.

Graphics Drivers

Ubuntu can readily install proprietary graphics drivers for you (NVidia, ATI), but you need to explicitly do it: System -> Administration -> Hardware Drivers -> click the one you want -> Activate (restart probably required). These drivers are not automatically installed because they are not open source - they are packages containing propreitary software.


Desktop The Infamous Desktop Cube

If you have a decent graphics card, and drivers installed, then some desktop effects should be enabled by default:
  • Window key+ e - show all desktops
  • Shift+alt+up arrow - show all windows
  • Window key+n - invert the colors of the current window
To get the desktop cube, you'll need to install the settings manager for the desktop effects, which is actually it's own project called compiz. Enter the following command in the terminal to install the settings manager:
sudo apt-get install compizconfig-settings-manager

Now open System -> Preferences -> CompizConfig Settings Manager. There, under "Desktop" check the box next to "Desktop Cube" (click yes, disable Desktop Wall) and also check "Rotate Cube" (Effects -> 3D Windows is cool too). Now try control+alt+arrows to switch between desktops. Control+alt+drag mouse lets you rotate the cube.

I hope you enjoy Ubuntu!

Please comment on this post if you have questions (such as "how do I do xyz that's really easy in Windows?"), comments, or suggestions for this introduction.

Eclipse Java development in Ubuntu

Updated 1/18/2009
In Ubuntu 8.10, here's how I got set up for Java EE development using Eclipse and OpenJDK.

Install Java:
sudo apt-get install openjdk-6-jdk -y

Install Eclipse
I don't recommend apt-get install eclipse, it installs an old version doesn't work for me. Install eclipse manually instead(taken from this guide):
# Download the latest eclipse
archive
mkdir ~/opt

cd ~/opt
wget http://mirrors.ibiblio.org/pub/mirrors/eclipse/technology/epp/downloads/release/ganymede/SR2/eclipse-jee-ganymede-SR2-linux-gtk.tar.gz
tar xzvf eclipse-jee-ganymede-SR2-linux-gtk.tar.gz

# create the launcher script and give it execute permissions
sudo sh -c 'echo "#!/bin/sh \n export ECLIPSE_HOME=\"\$HOME/opt/eclipse\" \n \$ECLIPSE_HOME/eclipse \$*" > /bin/eclipse'

sudo chmod +x /bin/eclipse
Now you can run eclipse by hitting alt+f2 and typing "eclipse"

Script
I created a shell script of these instructions, and it can be executed with:
wget http://bitbucket.org/curran/ubuntuautomation/raw/aa93f53ada5a/install_eclipse.sh && sh ./install_eclipse.sh

Enjoy!

Links:
Ubuntu Eclipse guide
A nice installation tutorial
Another good Ubuntu tutorial

Saturday, January 17, 2009

WSAS IDE Broken

A summary of my first experience with WSAS IDE. Mostly taken from this great tutorial.

Download WSAS v2.3
unzip to C:\

in C:\wso2wsas-2.3\bin execute install.bat (JAVA_HOME must be set first)
choose 1) Eclipse WTP Plugin Installation
at "Please enter Eclipse WTP Home :", enter C:\Program Files\eclipse (or wherever yours is)
success!

Open Eclipse
Window -> Preferences -> Web Services -> WSAS Preferences -> set "WSAS Runtime" to "C:\wso2wsas-2.3" -> OK
New -> Project -> Web -> Dynamic Web Project -> Next -> under "Target Runtime" hit "New..." -> WSO2 -> WSO2 WSAS -> Finish -> ProjectName: "TestService"

I ran into a bug and got really frustrated, so I posted this to the WSAS Forum:

Hello, I am trying to get started with WSAS IDE, but constantly having the same problem. I followed this guide to get started. I am using Eclipse Ganymede for Java EE version 3.4.1, and WSAS 2.3. I'd like to use the beta, but it doesn't contain the WSAS IDE installer (or does it? am I missing it?).

Here's the bug: In both Windows XP and Ubuntu Hardy, when I go New -> Project -> Web -> Dynamic Web Project -> set Target Runtime to WSO WSAS, I get the error message "Runtime "WSO2 WSAS" is invalid. Missing classpath entry \serverRootDirectory\lib"

The problem is documented by others here and here. The only solution I have seen is to unjar org.wso2.wsf.ide.server.wsas-2.2.jar, edit the file wsas.serverdef, setting the "default" field to point to your WSAS directory, rejar the file, and replace the old jar.

This is ridiculous. I really want to use WSAS IDE in my group, but I'll have a hard time convincing the group to adopt it when it requires something this silly to get working at all.

This bug is a deal breaker.

Does anyone know if this will be fixed in 3.0? Is there a recommended older version that doesn't have this problem?

Thanks very much, any help is greatly appreciated!


Links:

WSO Tutorial from 2007
IBM Tutorial from 2008 (really good!)
WSAS Documentation
WSAS IDE Instructions

Forum Thread on classpath error

Tuesday, December 9, 2008

Why isn't it easy in python to create an array of all zeros?

...wait a minute, how can I create an array of a size n filled with zeros in Python?

I am very frustrated that this seems nearly impossible. This should be trivial, but I see no built in Python function to do this.

Java -> int[] a = new int[n];

Python -> a = []; for i in range(0,5): a.append(0)

There must be a better way! Why is this so hard to find? I came across this page who said "just use zeros(n)" .. well ..

zeros(n) results in "NameError: name 'zeros' is not defined" ... oh, you need "import numpy"? thanks for leaving that detail out completely...

I need to import something to create an array of a given size containing all zeros? what? ...but wait,

import numpy; results in "ImportError: No module named numpy" Woah, NumPy is not there by default? I need to install an extra package, which other machines aren't guaranteed to have, meaning my code has an extra dependency just because it creates an zeroed array in one line?

Why isn't this easy? Python has been good to me most of the time, but this is so frustrating - why force the programmer to iterate through an array of [1,2,3,4,5] adding 5 zeros, either that or install an extra package? This is nuts.

I'd like to think that I am the one missing something, and there is a better way. Do you know of one?

**update**

Found it:

Python: a=[0]*n
Java: int[] a = new int[n]

much better.

jeez that took way too long to find. Here are some search beacons for people who have the same issue:
how to create a n array of length in in python
python predetermined size array
python zero function missing

Monday, November 17, 2008

Global String Replace in all PHP files in a given directory tree

The beauty of the unix shell never ceases to amaze me. I wanted to install an email notification plugin for two wordpress blogs that are using the same database. Unfortunately, the email plugin always uses a hard-coded table name in the database you give it on installation, so the two plugins for the separate blogs end up using the same database table, forwarding emails from both blogs to everyone on that list.

To fix this, I needed to replace all instances of the hard-coded table name 'wp_email_list' in all the PHP files (all in the ./temp directory) with something else, say 'wp_email_list_2', before running the install script. I figured out how to do this with one line of Unix:

find ./temp -name '*.php' | xargs sed -i 's/wp_email_list/wp_email_list_2/g'

Here's where it's used

Friday, November 14, 2008

Interfacing to R from Java

I'd like to write some Java code which interfaces to R (a statistical computing language). This post describes how to set up and code a Java program which interfaces to R. Here's how I did it in Ubuntu Linux and Eclipse:

#install R
sudo apt-get install r-base
#install rserve
sudo apt-get install r-cran-rserve
#start Rserve as a daemon (
default port for Rserve is 6311)
R CMD Rserve


#Make a Java project in Eclipse.
#Make a directory called lib under that project.
#Open a terminal, go to the lib directory, execute
wget http://www.rforge.net/Rserve/files/RserveEngine.jar
wget http://www.rforge.net/Rserve/files/REngine.jar

In Eclipse, refresh (F5), right click those library files -> add to build path.

Paste the following code:
public static void main(String[] args) {
try {
// Establish the R connection
RConnection c = new RConnection();

// Create test data (Java array, R Vector)
int n = 100;
double[] dataX = new double[n];
double[] dataY = new double[n];

for (int i = 0; i < l =" c.eval(" lx =" (double[])" ly =" (double[])" lx = "); for (int i = 0; i < n; i++) System.out.print(lx[i]+" ly = "); for (int i = 0; i < n; i++) System.out.print(ly[i]+">
I also figured out how to start Rserve from within Java. Here's the code:
public static void main(String[] args) {
Rconnection c = getLocalRconnection();
if (c != null) {
try {
double[] d = c.eval("rnorm(10)").asDoubleArray();
for (double n : d)
System.out.println(n);
} catch (RSrvException e) {
e.printStackTrace();
}
}
}

private static Rconnection getLocalRconnection() {
try {
return new Rconnection();
} catch (RSrvException e) {
//If we get this kind of error, it may be because Rserve is not running
if (e.getMessage().equals("Cannot connect: Connection refused")) {
try {
String rserveStartCommand = "R CMD Rserve --vanilla";
//do a blocking call to the shell command for starting Rserve
int exitValue = Runtime.getRuntime().exec(rserveStartCommand).waitFor();
//if it returned success, try connecting again
if (exitValue == 0)
return new Rconnection();
//otherwise, Rserve is probably not installed
else
System.err.println("Could not start Rserve - is it installed properly? Shell command \""+rserveStartCommand+"\" exited with exit value "+exitValue+".");
} catch (Exception e1) {
e1.printStackTrace();
}
}
else
e.printStackTrace();
}
return null;
}
Enjoy!

Links:
Rserve downloads (includes libs)

Thursday, November 13, 2008

First Stab: JAX-WS Web Services in Ubuntu

Raw personal notes from my first experience installing GlassFish and deploying a WebService. I'll be posting a cleaned up version soon.

From a fresh Ubuntu 8.10 install:

sudo apt-get install openjdk-6-jdk glassfishv2 -y

Now the server is installed and started - go to http://localhost:8080/ to see.

I guess install-dir is /usr/share/glassfishv2

..from QuickStart...

Add path to PATH:
echo "PATH=\$PATH:/usr/share/glassfishv2/bin
export PATH" >> ~/.bashrc
restart terminal

After some hunting, I found from the config file (asenv.conf) from the line:
AS_DEF_DOMAINS_PATH="/var/lib/glassfishv2/domains"
that the "domains" directory is here (different from the outdated QuickStart):
/var/lib/glassfishv2/domains

Deploy a test:
wget http://glassfish.dev.java.net/downloads/quickstart/hello.war
mv hello.war /var/lib/glassfishv2/domains/domain1/autodeploy/
It worked! go to http://localhost:8080/hello/
  • War files can be deployed in GlassFish by putting them in autodeploy.
Web Admin of Glassfish:
Go to http://localhost:4848/ user: admin pass: adminadmin
sweet!

...from Building a JAX-WS Application in the Metro Environment...

wget https://metro.dev.java.net/getting-started/wsit-jaxws-fromjava.zip
unzip wsit-jaxws-fromjava.zip
rm wsit-jaxws-fromjava.zip
cd wsit-jaxws-fromjava/
AS_HOME=/usr/share/glassfishv2/bin
export AS_HOME
ant server

it breaks because it's expecting domains/domain1 to be under /usr/share/glassfishv2/bin, but instead it's under /var/lib/glassfishv2/.
comment out line 235 of build.xml


try again:
ant server

Now there is a war, which we can move into autodeploy:
sudo mv ./build/war/wsit-jaxws-fromjava.war /var/lib/glassfishv2/domains/domain1/autodeploy/

Verify that it's working:
http://localhost:8080/wsit-jaxws-fromjava/addnumbers?wsdl

building the client:
and ///arrgh - persueing another path, this ant execution is all messed up

...using Developing Metro in Eclipse...
Eclipse can't access the domain. solution [seems like a hack - why is is like this in the first place? is it normal for the root to own the default domain?]:
sudo chmod -R 777 /var/lib/glassfishv2

..after following instructions...

it works!!

..Addendum..
to start glassfish, execute
/usr/share/glassfishv2/bin/asadmin start-domain domain1
user: admin
pass: adminadmin

Links:
Glassfish: getting started
Getting Started with Metro
Some guy's installation notes
Developing Metro in Eclipse

Wednesday, November 12, 2008

Recursive Word Count

Here is a golden link I dug up recently for how to do recursive line count in Unix - it will tell you how many lines of Java code total are in a given directory:

wc -l `find . -name *.java`

Ahh, beautiful!

Wednesday, October 29, 2008

Wordpress Email Notifications

I want Wordpress to notify people through email of new posts. Here's how I got email notifications working on my existing installation.

In your wordpress directory (the one which contains wp-content):
wget http://www.watershedstudio.com/files/email_notification_v2.3.1.zip
unzip email_notification_v2.3.1.zip -d ./temp
#The following line is a hack to use a different table name than the default (to keep two installations in the same database distinct)
#find ./temp -name '*.*' | xargs sed -i 's/wp_email_list/wp_email_list_2/g'
cp -r temp/maillist/ ./maillist/
cp -r temp/wordpress/wp-content/plugins/wp-email-notification/ ./wp-content/plugins/wp-email-notification/
chmod 666 maillist/wpemn_config.php
rm -r ./temp
rm email_notification_v2.3.1.zip

open in a browser yoursite.com/maillist/install.php
In the installer, be sure to set: Default Notification Value: Yes - this triggers sending notifications for new posts.

After finishing that, remove the installer:
rm maillist/install.php

Go to yoursite.com/wp-admin/plugins.php and click "activate" next to the entry WordPress Email Notification Plugin v2.3.1

Now you should have an admin GUI under Manage -> Email Notification

The last thing is to add a text box somewhere for the user to subscribe to the mailing list. We need get our hands dirty and edit some PHP to do this. I wanted to add it to the sidebar, so I added
<li><h3>Email Notifications</h3>
<form method="post" action="maillist/index.php">Enter your e-mail address here to receive notifications of new posts<br />
<input type="text" name="email" size="12" maxlength="50" />
<input type="submit" name="submit" value="Sign me up!" />
</form>
</li>

to the file wp-content/themes/aeros/sidebar.php (I'm using the aeros theme, this will be whatever theme you are using, and the placement may be different), right before the end - before these lines
</ul>

</div><!-- end sidebar -->


It works!!!

Email Notification Plugin - Instructions taken mostly from the install.txt in this download.

Monday, October 27, 2008

Algorithms in LaTeX

I was pleased to find that getting your pseudocode to look exactly like the code in Introduction to Algorithms textbook is straightforward - just use this clrscode package!

If you're using texlive, you can install the clrscode package by installing the following Ubuntu package:
sudo apt-get install texlive-science

Tuesday, September 30, 2008

Using Vim for LaTeX

I found myself wanting some of the nice features of Vim while editing LaTeX in Kile, so I tried using Vim for LaTeX. It works very well, and I figured out a great way of setting up - mapping a keystroke to compiling the LaTex document, and having a document viewer constantly open, looking at the LaTeX output. Keeping one viewer open the advantage over opening a new one every time that it stays in the same place in the document.

The puzzle I solved and want to share with the world is how to add the feature that ctrl+F11 maps to the action of compiling the currently open document and clearing the terminal when no errors occurred, using one console command. Here it is:

echo 'map :w:!latex % && clear' >> ~/.vimrc

Enjoy!
Compiling LaTeX within vim

Wednesday, September 24, 2008

Installing a WordPress Blog

Here's how I ended up installing a WordPress blog on a server at my university:

# ssh into the server:
ssh username@host.name

# Create the directory for the blog:
cd public_html
mkdir blogdirectory

# Download and unzip WordPress there
cd blogdirectory
wget http://wordpress.org/latest.zip
unzip wordpress-2.6.3.zip
mv wordpress/* ./
rm wordpress-2.6.3.zip
rm -r wordpress

# Edit wp-config.php
mv wp-config-sample.php wp-config.php
# Edit the database details of wp-config.php

#Install to the Database
Navigate in a web browser to the location of the blog, this will start an install process which asks for a blog title and your email. That's it!

Editing Themes
I wanted the posts to show the author. It turns out there is no GUI for this, you need to edit a PHP file. It turned out to be very easy - just change line 11 in blog/wp-content/themes/default/index.php from
<small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>
to
<small><?php the_time('F jS, Y') ?>  by <?php the_author() ?> </small>

Also, you could give write permissions to all the theme files, so you could use the WordPress Theme Editor GUI for editing the PHP files:
cd blog
chmod -R 777 wp-content

Password Protecting the Directory
cd blog
# Create the password file
htpasswd -c .htpasswd username
# Create the .htaccess file, changing /full/path/to/.htpasswd to the path to the blog directory, and "Password Protected Site"" to the message you want displayed to users as the password is being asked for
echo "AuthUserFile /full/path/to/.htpasswd
AuthType Basic
AuthName \"Password Protected Site\"
Require valid-user" > .htaccess

I moved the blog directory without following the instructions, so I had to do some rearranging which involved creating a symlink from the old directory to the new one (where newlocation and oldlocation are the full paths to your new and old locations on the same server)
ln -s newlocation oldlocation
Then I changed the URL in the WordPress admin GUI to the new one (accessed from the old location through the symlink) Then I removed the symlink
unlink oldlocation

Installing a Theme
I picked the Aero theme from here
cd wp-content/themes/
wget http://wordpress.org/extend/themes/download/aeros.1.0.4.zip
unzip aeros.1.0.4.zip
rm aeros.1.0.4.zip
Now you can navigate to the themes page of the GUI and select the new theme.

Changing the Maximum Upload Size
I tried to upload media from the posts page, and it told me "This file is too big. Your php.ini upload_max_filesize is 2M" I found this post, and their method worked - adding some stuff to .htaccess. Here's what I did:
cd blog
echo "php_value upload_max_filesize 30M
php_value post_max_size 30M
php_value memory_limit 128M
php_value max_execution_time 3600" >> .htaccess

Using LaTeX
Here is the site of the LaTeX Wordpress plugin. Here's how to install it:
cd blog/wp-content/plugins
wget http://downloads.wordpress.org/plugin/latex.zip
unzip latex.zip
rm latex.zip
cd ../../wp-content
mkdir cache
chmod 777 cache
Now go to the plugins page from the WordPress GUI, and click "Activate" next to "Latex for WordPress" to enable the plugin. Now, text surrounded by $$...$$ will appear as beautiful rendered image of LaTeX. This plugin uses the WordPress.com LaTeX service. Try this for example:
$$\Theta = \Omega(\delta)$$
Appears as



You can also add email notifications of posts.

Enjoy!

Links:
Official Install Page
move instructions
LaTeX plugin

Tuesday, September 23, 2008

Remove Files By Type in Unix

This is sweet! Remove all files except those ending in .tex:

rm !(*.tex)

Links:
Original

Monday, September 22, 2008

Setting Up Tomcat

Tomcat setup in Ubuntu 8.04:

#Install OpenJDK
sudo apt-get install openjdk-6-jre openjdk-6-jdk -y
sudo update-java-alternatives -s java-6-openjdk

#Install Tomcat
sudo apt-get install tomcat5.5 -y

We can see it's running by executing
sudo /etc/init.d/tomcat5.5 status
stop it with
sudo /etc/init.d/tomcat5.5 stop
start it with
sudo /etc/init.d/tomcat5.5 start

Links:
Nice Setup guide

Password Protecting a Folder

I wanted to password protect an entire directory of a website. Here's a great guide for using .htaccess.

Monday, September 8, 2008

Starting to Learn Flex

I want to do development in Ubuntu Linux, here's how I got started:
#install the Flash plugin
sudo apt-get install flashplugin-nonfree

# Install Sun's Java
sudo apt-get install sun-java6-jdk
the "java" command still points to the old version. We can change that with
sudo update-java-alternatives -s java-6-sun

# Install the Flex SDK (I chose the most recent fully Open Source version from the download page)
wget http://flexorg.wip3.adobe.com/flexsdk/3.1.0.2710/flex_sdk_3.1.0.2710_mpl.zip
sudo unzip -d /opt/flex_sdk_3 flex_sdk_3.1.0.2710_mpl.zip
sudo chmod +x /opt/flex_sdk_3/bin/mxmlc
rm flex_sdk_3.1.0.2710_mpl.zip

# Add the Flex compiler to your path
echo "# Flex stuff
PATH=\$PATH:/opt/flex_sdk_3/bin
export PATH" >> ~/.bashrc
# restart the terminal for the changes to take effect.
# test if it worked by typing "mxmlc"
I got the error:
bash: /opt/flex_sdk_3/bin/mxmlc: /bin/sh^M: bad interpreter: No such file or directory

What?! The dos newlines are causing errors in the shell script? Arrgh
sudo apt-get install tofrodos
sudo dos2unix /opt/flex_sdk_3/bin/mxmlc

# Compile and Run an Example (taken from Here)
# Put the following text in button.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
horizontalAlign="center" verticalAlign="center"
>

<mx:Button id="myButton" label="I'm a button!" />
</mx:Application>
# Compile it into an SWF
mxmlc button.mxml
# Run it in firefox
firefox button.swf

Hooray!!!

..more to come

Links:
Installation Tips
Wikipedia: Flash, Flex, ActionScript
Adobe Flex Open Source download page
Older guide to installinf Flex in Ubuntu
Blog about learning Flash
Linux Flex Tutorial
Adobe Flex - Getting Started
FLEX and BlazeDS

Friday, September 5, 2008

Setting the Background with a Command

# Get the picture from a URL
wget http://farm2.static.flickr.com/1121/1383497195_9baa091855_o.jpg -O ~/background.jpg

# Set the background
gconftool-2 -t string -s ~/background.jpg

Tuesday, September 2, 2008

Setting Up Synergy

Synergy is a really cool thing that lets you use one keyboard and mouse to control many separate computers and have a common clipboard (they can even be running different operating systems!) I want to set up my desktop to control my laptop (as though it were a third monitor in addition to my dual head desktop). Instructions for Windows and Mac can be found in the Synergy documentation. Here's how I got it working in Ubuntu Linux:

Setting Up
On both computers, install Synergy (green commands can be pasted into the terminal with ctrl+insert)
sudo apt-get install synergy -y

We'll need the host names of the two computers to use in the config files. Go to the computer on the left and execute the command hostname. Here's a sample output:
$hostname
awesomedesktop

Now do the same for the machine on the right:
$hostname
awesomelaptop

One of them is going to be the server, lets say the one on the left - awesomedesktop. In the computer at the left, execute the following commands, but replace "awesomelaptop" with the hostname of the computer on the right.
screen1=`hostname`
screen2=awesomelaptop

Or, it the server is on the right, swap 1 and 2:
screen2=`hostname`
screen1=awesomelaptop

Paste all of this at once into the terminal:
echo "section: screens
$screen1:
$screen2:
end
section: links
$screen1:
right = $screen2
$screen2:
left = $screen1
end" > ~/.synergy.conf

To see the contents of the new file, execute
cat .synergy.conf

Getting it Going
On the computer on the left, start the synergy server by executing
synergys -f

On the computer on the right, start the client by executing
synergyc -f server-ip
where server-ip is replaced by the IP address of the server, which can be obtained by executing (on the server)
ifconfig
or to get only the IP address:
ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' |cut -d: -f2 | awk '{ print $1}'

Starting it Automatically
Automatically starting things go in ~/.profile, so we'll put our commands there.
On the server, execute:
echo synergys >> ~/.profile
On the client (again replacing server-ip):
echo synergyc server-ip >> ~/.profile

Enjoy!

Links:
Synergy documentation
Ubuntu Synergy Documentation

Assigning a Static IP address in Ubuntu

I had some internet problems at a hotel, and I learned a bit about networking. My Ubuntu 8.04.1 desktop said "Wired network connection with a self-assigned address", and wouldn't connect to the internet, while at the same time my Ubuntu laptop was accessing the internet just fine. After a while talking with the help desk people, I learned that it was because the desktop was not being assigned an IP address by the DHCP server. Here are some useful things I learned:

To find out your own IP and MAC address:
ifconfig
IP address is labeled "inet addr", and MAC address is labeled "HWaddr"

To manually assign your computer a static IP address given to you in the command line:
Temporarily
Permanently
Or use the GUI:
System -> Administration -> Network
Here you need to hit "Unlock" at the bottom. I missed this fact and thought the GUI was useless for a while.

I tried setting all the information from the command line, but it didn't work until I just opened and closed the GUI, so I guess I was missing some kind of initialization or reset command.

It was suggested that I need to change my link speed from 100 to 10, and duplex mode from full to half. To see your current configuration, use
sudo ethtool eth0

To set the link speed to 100, and set half duplex, execute
sudo ethtool -s eth0 speed 10 duplex half

To get assigned an IP address (or at least attempt to), execute
sudo dhclient eth0

You should see "bound to 169.168...." or something. If the address begins with 196.254...., then it was not assigned by the DHCP server, it was self-assigned, meaning it cannot connect to the internet.

Sunday, August 31, 2008

muParser

I was thinking of using muParser, a fast math parser C++ library, in some projects. Here's how I got it working in Ubuntu with a test program.

#Install the muParser library and headers
sudo apt-get install libmuparser0 libmuparser-dev -y

I was appalled to see that the sample code didn't work ("pi" was used but not defined)! The lines in red are the changed I had to make to get it to work. Paste this into test.cpp:
#include "muParser/muParser.h"
#include <math.h>
// Function callback
double MyFunction(double a_fVal)
{
return a_fVal*a_fVal;
}

// main program
int main(int argc, char* argv[])
{
using namespace mu;

try
{
double fVal = 1;
Parser p;
p.DefineConst("pi", M_PI);
p.DefineVar("a", &fVal);
p.DefineFun("MyFunc", MyFunction);
p.SetExpr("MyFunc(a)*pi+min(10,a)");
std::cout << p.Eval() << "\n";
}
catch (Parser::exception_type &e)
{
std::cout << e.GetMsg() << "\n";
}
return 0;
}

Compile and run it with
g++ test.cpp -lmuparser && ./a.out

Here's an example which takes an expression, and generates a table if input and output values:
#include "muParser/muParser.h"
#include <math.h>
using namespace mu;
using namespace std;

int main(int argc, char* argv[])
{
Parser p;
double x = 0;
char input[80];

p.DefineConst("pi", M_PI);
p.DefineConst("e", M_E);
p.DefineVar("x", &x);

cin >> input;
p.SetExpr(input);
try
{
for(x = -10; x <= 10;x++)
cout << "X = " << x << "\t" << input << " = " << p.Eval() << "\n";
}
catch (Parser::exception_type &e)
{
std::cout << e.GetMsg() << "\n";
}
return 0;
}

If you save it as table.cpp, compile and run with
g++ table.cpp -lmuparser && ./a.out

Enter expressions into the console like this:
sin(x^2)
and you'll get this:
X = -10    sin(x^2) = -0.506366
X = -9 sin(x^2) = -0.629888
X = -8 sin(x^2) = 0.920026
X = -7 sin(x^2) = -0.953753
X = -6 sin(x^2) = -0.991779
X = -5 sin(x^2) = -0.132352
X = -4 sin(x^2) = -0.287903
X = -3 sin(x^2) = 0.412118
X = -2 sin(x^2) = -0.756802
X = -1 sin(x^2) = 0.841471
X = 0 sin(x^2) = 0
X = 1 sin(x^2) = 0.841471
X = 2 sin(x^2) = -0.756802
X = 3 sin(x^2) = 0.412118
X = 4 sin(x^2) = -0.287903
X = 5 sin(x^2) = -0.132352
X = 6 sin(x^2) = -0.991779
X = 7 sin(x^2) = -0.953753
X = 8 sin(x^2) = 0.920026
X = 9 sin(x^2) = -0.629888
X = 10 sin(x^2) = -0.506366

Enjoy!

Links:
muParser web site

Thursday, August 28, 2008

CUDA in Ubuntu, a hack

This is an outdated way of setting up CUDA 1.1 in Ubunt 8.04. I'm posting it just so it's not lost. An up to date guide can be found here.

This guide is written to work with a fresh installation of Ubuntu 8.04 (Hardy Heron).

Green means it is a command. You can paste lines into the console with ctrl+shift.

#install drivers from Ubuntu
sudo apt-get install nvidia-glx-new -y
sudo nvidia-xconfig

#reboot
sudo reboot

#install the toolkit (doesn't work with findcuda.CMake)
wget http://developer.download.nvidia.com/compute/cuda/1_1/Linux/toolkits/NVIDIA_CUDA_Toolkit_1.1_Ubuntu7_x86.run
chmod +x NVIDIA_CUDA_Toolkit_1.1_Ubuntu7_x86.run
sudo ./NVIDIA_CUDA_Toolkit_1.1_Ubuntu7_x86.run auto
rm NVIDIA_CUDA_Toolkit_1.1_Ubuntu7_x86.run

Alternatively, use the beta (works with findcuda.CMake):
wget http://developer.download.nvidia.com/compute/cuda/2.0-Beta2/linux/toolkit/NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run
chmod +x NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run
sudo ./NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run auto
rm NVIDIA_CUDA_Toolkit_2.0beta2_Ubuntu7.10_x86.run

#add environment variables
echo "# CUDA stuff
PATH=\$PATH:/usr/local/cuda/bin
LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/cuda/lib
export PATH
export LD_LIBRARY_PATH" >> ~/.bashrc

#restart the terminal for the changes to take effect
exit

#install the SDK (hit enter at all prompts)
wget http://developer.download.nvidia.com/compute/cuda/1_1/Linux/sdk/NVIDIA_CUDA_SDK_1.1_Linux.run
chmod +x NVIDIA_CUDA_SDK_1.1_Linux.run
./NVIDIA_CUDA_SDK_1.1_Linux.run

#install the libcuda.so file, which the Ubuntu installer doesn't do
wget http://us.download.nvidia.com/XFree86/Linux-x86/169.12/NVIDIA-Linux-x86-169.12-pkg1.run
chmod +x NVIDIA-Linux-x86-169.12-pkg1.run
./NVIDIA-Linux-x86-169.12-pkg1.run --extract-only
sudo mv NVIDIA-Linux-x86-169.12-pkg1/usr/lib/libcuda.so.169.12 /usr/lib/libcuda.so
rm ./NVIDIA-Linux-x86-169.12-pkg1.run
rm rm -r -f NVIDIA-Linux-x86-169.12-pkg1

#install build tools
sudo apt-get install build-essential libglut3-dev gcc-4.1 g++-4.1 -y

#set up gcc and g++ to use version 4.1 (otherwise we get compatibility issues)
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.1 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.1
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.2 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.2

#make the example projects
cd NVIDIA_CUDA_SDK/
make

#Run an example program and be overwhelmed with parallel bliss
~/NVIDIA_CUDA_SDK/bin/linux/release/fluidsGL

Ways to Install NVidia Drivers in Ubuntu

Here are some ways of geting NVidia drivers working in Ubuntu 8.04 that have worked for me.

Using Ubuntu's Installer
sudo apt-get install nvidia-glx-new -y
sudo nvidia-xconfig
sudo reboot

Using EnvyNG
sudo apt-get install envyng-gtk -y
envyng -t
# type "1" to install NVidia drivers
# then "y" to restart

Using NVidia's Installer
#from http://www.nvidia.com/object/cuda_get.html -> Linux 32 bit
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/driver/NVIDIA-Linux-x86-177.67-pkg1.run
chmod +x ./NVIDIA-Linux-x86-177.67-pkg1.run
sudo /etc/init.d/gdm stop
sudo ./NVIDIA-Linux-x86-177.67-pkg1.run
rm ./NVIDIA-Linux-x86-177.67-pkg1.run
sudo /etc/init.d/gdm start
# this next step resolves a driver conflict.
# if we don't do this, the machine will start in low-graphics mode on reboot
sudo gedit /etc/default/linux-restricted-modules-common
# add 'nv' to DISABLED_MODULES ('DISABLED_MODULES="nv"')
sudo reboot

Failed CUDA Install Attempts

Here's a collection of approaches of setting up CUDA 2.0 in Ubuntu 8.04 which failed. I wrote a functioning guide for how to do it here, I'm posting these failures just for reference.

Using EnvyNG
# Install the NVidia drivers with EnvyNG
sudo apt-get update
sudo apt-get install envyng-gtk -y
envyng -t
# type "1" to install NVidia drivers
# then "y" to restart

# Install the CUDA Toolkit
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/toolkit/NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run
chmod +x NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run
sudo ./NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run auto
rm NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run

# add environment variables
echo "# CUDA stuff
PATH=\$PATH:/usr/local/cuda/bin
LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/cuda/lib
export PATH
export LD_LIBRARY_PATH" >> ~/.bashrc

# Install the CUDA SDK
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/sdk/NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run
chmod +x ./NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run
./NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run
# press enter at both prompts
rm ./NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run

# Install the build tools we need
sudo apt-get install build-essential libglut3-dev -y

# compile and run an example
cd NVIDIA_CUDA_SDK/
make
~/NVIDIA_CUDA_SDK/bin/linux/release/fluidsGL

FluidsGL runs but fails with:
cufft: ERROR: CUFFT_EXEC_FAILED
cufft: ERROR: /root/cuda-stuff/sw/rel/gpgpu/toolkit/r2.0/cufft/src/cufft.cu, line 119
cufft: ERROR: CUFFT_EXEC_FAILED
cufft: ERROR: /root/cuda-stuff/sw/rel/gpgpu/toolkit/r2.0/cufft/src/execute.cu, line 1038
cufft: ERROR: CUFFT_EXEC_FAILED
cufft: ERROR: /root/cuda-stuff/sw/rel/gpgpu/toolkit/r2.0/cufft/src/execute.cu, line 284


Using NVidia's Installer for Ubuntu 7.10
# --- Install the NVidia Driver ---
#from http://www.nvidia.com/object/cuda_get.html -> Linux 32 bit, Ubuntu 7.10
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/driver/NVIDIA-Linux-x86-177.67-pkg1.run
chmod +x ./NVIDIA-Linux-x86-177.67-pkg1.run
# Install build tools needed for the installer to compile the drivers
sudo apt-get install build-essential -y
# this will kill the window manager and kick you down to a terminal
sudo /etc/init.d/gdm stop
sudo ./NVIDIA-Linux-x86-177.67-pkg1.run
rm ./NVIDIA-Linux-x86-177.67-pkg1.run
sudo /etc/init.d/gdm start
#desktop effects are working! Success!

# --- Install the CUDA Toolkit and SDK
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/toolkit/NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run
chmod +x NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run
sudo ./NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run
sudo apt-get install libglut3-dev -y
rm NVIDIA_CUDA_Toolkit_2.0_ubuntu7.10_x86.run
wget http://developer.download.nvidia.com/compute/cuda/2_0/linux/sdk/NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run
chmod +x ./NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run
./NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run auto
#add environment variables
echo "# CUDA stuff
PATH=\$PATH:/usr/local/cuda/bin
LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/cuda/lib
export PATH
export LD_LIBRARY_PATH" >> ~/.bashrc
rm ./NVIDIA_CUDA_SDK_2.02.0807.1535_linux.run
Works great! until reboot, then the machine starts in low graphics mode. Any ideas on how to fix this?
FIXED! Solution: add 'nv' to DISABLED_MODULES in /etc/default/linux-restricted-modules-common,full instructions here

Thursday, August 14, 2008

OpenGL example: Rendering Cylinders and Spheres, with Point-Cylinder Inside Test

This is a working example illustrating how the cylinder rendering, sphere rendering, and point-cylinder inside test functions are used.

If you copy it into the file example.c, compile and run it with the command
gcc -lglut -lGL example.c && ./a.out
//This code is in the public domain.
#include <GL/glut.h>
#include <GL/gl.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define ESCAPE_KEY 27

float window;
float t = 0.0f;
int pointIsInsideCylinder(float x1, float y1, float z1, float dx,float dy, float dz, float lengthSquared,float radiusSquared ,float xTest,float yTest,float zTest)
{
float pdx = xTest - x1;
float pdy = yTest - y1;
float pdz = zTest - z1;
float dot = pdx * dx + pdy * dy + pdz * dz;
int pointIsInside = 0;
if( dot > 0 && dot < lengthSquared )
pointIsInside = pdx*pdx + pdy*pdy + pdz*pdz - dot*dot/lengthSquared < radiusSquared;
return pointIsInside;
}
int pointIsInsideCylinder_convenient( float x1, float y1, float z1, float x2,float y2, float z2, float radius, float xTest,float yTest,float zTest)
{
//these things need only to be computed once for a cylinder, and reused for each test point
float dx = x2 - x1;
float dy = y2 - y1;
float dz = z2 - z1;
float lengthSquared = pow(x2-x1,2)+pow(y2-y1,2)+pow(z2-z1,2);
float radiusSquared=radius*radius;
return pointIsInsideCylinder(x1,y1,z1,dx,dy,dz,lengthSquared,radiusSquared,xTest,yTest,zTest);
}


void renderCylinder(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions,GLUquadricObj *quadric)
{
float vx = x2-x1;
float vy = y2-y1;
float vz = z2-z1;

//handle the degenerate case of z1 == z2 with an approximation
if(vz == 0)
vz = .00000001;

float v = sqrt( vx*vx + vy*vy + vz*vz );
float ax = 57.2957795*acos( vz/v );
if ( vz < 0.0 )
ax = -ax;
float rx = -vy*vz;
float ry = vx*vz;
glPushMatrix();

//draw the cylinder body
glTranslatef( x1,y1,z1 );
glRotatef(ax, rx, ry, 0.0);
gluQuadricOrientation(quadric,GLU_OUTSIDE);
gluCylinder(quadric, radius, radius, v, subdivisions, 1);

//draw the first cap
gluQuadricOrientation(quadric,GLU_INSIDE);
gluDisk( quadric, 0.0, radius, subdivisions, 1);
glTranslatef( 0,0,v );

//draw the second cap
gluQuadricOrientation(quadric,GLU_OUTSIDE);
gluDisk( quadric, 0.0, radius, subdivisions, 1);
glPopMatrix();
}
void renderCylinder_convenient(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions)
{
//the same quadric can be re-used for drawing many cylinders
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricNormals(quadric, GLU_SMOOTH);
renderCylinder(x1,y1,z1,x2,y2,z2,radius,subdivisions,quadric);
gluDeleteQuadric(quadric);
}
void renderSphere(float x, float y, float z, float radius,int subdivisions,GLUquadricObj *quadric)
{
glPushMatrix();
glTranslatef( x,y,z );
gluSphere(quadric, radius, subdivisions,subdivisions);
glPopMatrix();
}

void renderSphere_convenient(float x, float y, float z, float radius,int subdivisions)
{
//the same quadric can be re-used for drawing many spheres
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricNormals(quadric, GLU_SMOOTH);
renderSphere(x,y,z,radius,subdivisions,quadric);
gluDeleteQuadric(quadric);
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
glTranslatef(0,0,-7);

//define the cylinder
float x1 = sin(t);
float y1 = sin(t/2);
float z1 = cos(t*1.1);
float x2 = -sin(t*1.3);
float y2 = 0;
float z2 = -cos(t);
float radius = 0.03+(sin(t)/2+0.5)/3;

//render the cylinder
renderCylinder_convenient(x1,y1,z1,x2,y2,z2,radius,32);

//render spheres in a grid which are inside the cylinder
float gridSize = 20;
float xTest,yTest,zTest;
int x,y,z;
for(x = 0; x < gridSize,xTest = (float)x/gridSize*2-1; x++)
for(y = 0; y < gridSize,yTest = (float)y/gridSize*2-1; y++)
for(z = 0; z < gridSize,zTest = (float)z/gridSize*2-1; z++)
if(pointIsInsideCylinder_convenient(x1,y1,z1,x2,y2,z2,radius,xTest,yTest,zTest))
renderSphere_convenient(xTest,yTest,zTest,0.07,8);

t+=0.001;
glutSwapBuffers();
}
void InitGL(int Width, int Height)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);

glShadeModel(GL_SMOOTH);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);

glEnable(GL_LIGHTING);
GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);
glEnable(GL_LIGHT1);
}

void keyPressed(unsigned char key, int x, int y)
{
if(key == ESCAPE_KEY)
{
glutDestroyWindow(window);
exit(1);
}
}
int main( int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(640, 480);
window = glutCreateWindow("");
glutDisplayFunc(&display);
glutKeyboardFunc(&keyPressed);
glutFullScreen();
glutIdleFunc(&display);
InitGL(640, 480);
glutMainLoop();
return 1;
}
Enjoy!

Wednesday, August 13, 2008

Rendering a Sphere in OpenGL

There are a few little non-obvious OpenGL things you need for rendering a sphere. Here's a function which illustrates them:
void renderSphere(float x, float y, float z, float radius,int subdivisions,GLUquadricObj *quadric)
{
glPushMatrix();
glTranslatef( x,y,z );
gluSphere(quadric, radius, subdivisions,subdivisions);
glPopMatrix();
}

void renderSphere_convenient(float x, float y, float z, float radius,int subdivisions)
{
//the same quadric can be re-used for drawing many spheres
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricNormals(quadric, GLU_SMOOTH);
renderSphere(x,y,z,radius,subdivisions,quadric);
gluDeleteQuadric(quadric);
}
A complete OpenGL example using this function can be found here.