SyntaxHighlighter

Saturday, July 28, 2012

.pam_environment syntax in ubuntu

Some time ago, I started configuring my environment variables on ubuntu in /etc/profile. I thought I needed to set my environment variables in ~/.bashrc or ~/.bash_profile but when I open up terminals, they didn't seem to be used. So I resorted to the system-wide /etc/profile. I added things like JAVA_HOME, GROOVY_HOME, etc by adding lines like these at the bottom of the file:


export JAVA_HOME=/home/tim/apps/java/current
export GROOVY_HOME=/home/tim/apps/groovy/current

Each of those "current"  directories was a symlink to the version I was using. Then, I put bin directories in PATH variable.


export PATH=$PATH:$JAVA_HOME/bin:$GROOVY_HOME/bin


This all worked fine for me. But I learned that ubuntu was recommending user-specific environment variables in ~/.pam_environment. See https://help.ubuntu.com/community/EnvironmentVariables

I decided I'd move my configurations to the proper place and improve my linux knowledge. Being careful, however, I've only commented out the sections in /etc/profile so I could quickly revert them back, in case it somehow didn't work as expected.


On ubuntu help page mentioned above, it says:


~/.pam_environment - This file is specifically meant for setting a user's environment. It is not a script file, but rather consists of assignment expressions, one per line.

Assignment expressions. Ok. I'll just remove those "export" keywords.


JAVA_HOME=/home/tim/apps/java/current
GROOVY_HOME=/home/tim/apps/groovy/current
PATH=$PATH:$JAVA_HOME/bin:$GROOVY_HOME/bin

This should do it!


I rebooted the machine, got to the login screen, typed in my password, and then, typed in my password, typed in my password, and then.. errr... what is going on here?


It appeared to me that I wasn't able to login to my own account anymore! First, I was just annoyed. And then, I was afraid. How am I going to fix this, since I only have my own login to this machine, and the guest account can't do anything useful like changing someone else's configuration files.


Luckily, I was still able to use the browser logging in as "guest".
After googling around, I found I could boot into recovery mode by pressing left shift key while booting up. And then, googling around a bit more, I also discovered that the .pam_environment file has a special configuration format different to the usual /etc/profile.


What I had to follow was to use pam's configuration file style.
The whole thing was not quite clear to me, but reading man pages of pam and pam_env.conf gave me a hint as to how I should write my .pam_environment file.


So, after many reboots in recovery mode, dropping into command line as root, editing my .pam_environment to try different things, I came up with a working configuration:



JAVA_HOME=/home/tim/apps/java/current
GROOVY_HOME=/home/tim/apps/groovy/current
PATH DEFAULT=${PATH}:${JAVA_HOME}/bin:${GROOVY_HOME}/bin



I hope ubuntu help page will describe it a bit better in the future.

Tuesday, July 24, 2012

Calling closure in a Map

In groovy, you can store a piece of code in a Map (or even in List or whatever data structure you fancy), and call it when you want to.
It's a feature provided by closure.

For example, you can try this in groovy shell (groovysh):

groovy:000> a = [name: {return "Jack Sparrow"}]
===> {name=groovysh_evaluate$_run_closure1@26a0e990}
groovy:000> a.name
===> groovysh_evaluate$_run_closure1@26a0e990
groovy:000> a.name()
===> Jack Sparrow
groovy:000> a.name.call()
===> Jack Sparrow

But then, I was a bit confused by this:

groovy:000> a = [size: {return 5}]
===> {size=groovysh_evaluate$_run_closure1@707efa96}
groovy:000> a.size
===> groovysh_evaluate$_run_closure1@707efa96
groovy:000> a.size()
===> 1
groovy:000> a.size.call()
===> 5

Huh? Why is a.size() == 1?
I expected it to give 5.
But only when I added another closure, it dawned on me.

groovy:000> a = [age: {return 29}, size: {return 5}]
===> {age=groovysh_evaluate$_run_closure1@71257687, size=groovysh_evaluate$_run_closure2@5288d319}
groovy:000> a.age
===> groovysh_evaluate$_run_closure1@71257687
groovy:000> a.age()
===> 29
groovy:000> a.age.call()
===> 29
groovy:000> a.size
===> groovysh_evaluate$_run_closure2@5288d319
groovy:000> a.size()
===> 2
groovy:000> a.size.call()
===> 5

It might be very trivial to someone who's more familiar with groovy language, but it stumped me for a while.
Can you figure out what was going on?

Thursday, September 29, 2011

grails (un)install-plugin not cleaning up properly

It could be just me, but some plugins for grails don't work so well. For one of my grails projects, I had maven-publisher installed. When I saw that the release plugin is to replace maven-publisher plugin in the future, I thought I'd try it out. For the record, I had maven-publisher 0.8.1 installed. So, I did:
grails uninstall-plugin maven-publisher
grails install-plugin release
All seemed ok. It installed release plugin 1.0.0.RC3. There I tried this:
grails maven-install
It gave me this NPE bug:
java.lang.NullPointerException: Cannot get property 'file' on null object
Thankfully this bug was already logged and a patch attached too. See http://jira.grails.org/browse/GPRELEASE-23 for more details. Anyway, I decided to go back to the old maven-publisher for now. So I did:
grails uninstall-plugin release
grails install-plugin maven-publisher
Now, I was trying to maven-install again, and I get this error:
[...]
Dependencies resolved in 2207ms.
Running script /home/tlee/.grails/1.3.7/projects/myhumbleproject/plugins/maven-publisher-0.8.1/scripts/MavenInstall.groovy
Error executing script MavenInstall: No such property: releasePluginDir for class: MavenInstall
groovy.lang.MissingPropertyException: No such property: releasePluginDir for class: MavenInstall
	at MavenInstall.run(MavenInstall:17)
	at MavenInstall$run.call(Unknown Source)
	at gant.Gant.prepareTargets(Gant.groovy:606)
Error executing script MavenInstall: No such property: releasePluginDir for class: MavenInstall
I tried this:
grails clean
grails war
It asked if I wanted to uninstall svn-1.0.0.M1 which was installed by release plugin before. I said yes, and grails war script continues and builds the war file. I run:
grails maven-install
and I again get the same error as before. I tried removing entire $HOME/.ivy2/cache folder, and I still got the same error. And then, I tried removing entire $HOME/.grails/1.3.7/projects/myhumbleproject/ folder. Then:
grails maven-install
resulted in grails asking me back for clarification.
Running pre-compiled script
Script 'MavenInstall' not found, did you mean:
1) UninstallPlugin
2) InstallPlugin
3) InstallDependency
4) InstallTemplates
5) Init
Please make a selection or enter Q to quit: Q
Ha! Ok. I ran:
grails war
Then:
grails maven-install
Finally, it worked! It seems a compiled script remains even after uninstalling the release plugin.

Thursday, August 25, 2011

print text-graph in haskell!

Recently, I've been fascinated by haskell. Here's my take on the same problem in the previous post solved in haskell.
print_chars_list :: [Int] -> Char -> IO ()
print_chars_list [] _ = putStr ""
print_chars_list (x:xs) c = do
    putStrLn (take x $ repeat c)
    print_chars_list xs c

-- example
print_chars_list [1,5,4,6,2] '."

Text-graph

/**
Problem: Given a list of positive Integers and a Char,
print the Char n times per line.
Eg. if I have [1,3,2,5] and '.' I want the output of:
.
...
..
.....
*/

print_chars = { l, c ->
  l.each { n ->
    for (int i = 0; i < n; i++) {
      print c
    }
    println ""
  }
}

// try using it.
print_chars([1,3,2,5], '.')

Thursday, July 28, 2011

join and split

You can join elements in a List to form one String, and you can take a String and split it and put them into a List.


def langs = ['haskell', 'python', 'groovy', 'java', 'php', 'c']
println langs.join(' > ') // my interest level at the moment.
def scripts = "JavaScript, coffeeScript, clojureScript"
// notice again that there's no trailing colon ":" in below. Yay!
println scripts.split(',').collect { it.trim() }.join(":")


For some this is trivial, for others, not-so-trivial.
When I first encountered join() and split() in perl during my uni days, I thought this toy-like function wouldn't be really useful in real world applications. How wrong I was.
I'm not sure why this functionality never made into JDK still. Apache Common Lang's StringUtils is helpful here, but not when that function is the only thing I needed. I mean, am I the only one who wrote something like the following over and over again?


StringBuffer sb = "";
for (String s : list) {
sb.append(s).append(":");
}
String result = sb.toString().substring(0, sb.length() - 1);

Saturday, July 23, 2011

Dynamic type casting

Oh, I need to be careful with dynamic types in groovy.

If you do calculations on a BigDecimal with a Double (or double), you will get a Double back, not a BigDecimal.
Try the following in a groovyConsole to confirm.

import java.math.RoundingMode

def price = 10.25g
def tax = 1.1g
def afterTax = price * tax
println afterTax.getClass() // class java.math.BigDecimal
println afterTax.setScale(2, RoundingMode.HALF_UP) // 11.28

double tax_d = 1.1d
def afterTax_d = price * tax_d
println afterTax_d.getClass() // class java.lang.Double
println afterTax_d.setScale(2, RoundingMode.HALF_UP) // Will throw groovy.lang.MissingMethodException