Daily Archives: May 22, 2010

Tips for the Home Coder

I don’t know about anyone else but I spend a good amount of time coding at home.  It is nice because I get to drink beer and code at the same time.  It is tough to do because I have all my home duties plus getting an hour or two to make something fun or learn somethings.  I started to look at what I do at work to save time since “Time is Money” at work but “Time is Time” at home.  Here is a quick list.

Source Control

It sounds simple enough but I looked over the times where I have blasted my code at home and spent a week restoring while a simple “svn revert” would have done the trick.  For those who are worried about standing up a new server at home, don’t.  There are many sites out there that will host your code for free.  I keep all mine at darylmathisonblog.googlecode.com.  A lot of these sites do this for open source only so if you are making the next best mousetrap, you should take the time and stand one up at your abode.  Now all your changes are in one place that can be easily backed up by someone else or yourself.

Automated Testing

Automated testing is an investment in the future.  In the beginning, it is a real pain to set up, then it becomes awesome time saver. With the click of a button tests that could have taken minutes to finish by hand are done in seconds.  Unit tests can be combined and create test suites, now any change can be tested against the whole system or just that module.  Automated test can run while you make dinner or put the kids to bed.  The other neat thing, if you walk away from a project for a while the tests can give you an idea of how that module is supposed to run so you don’t spend a week of spare time figuring out your own code.  Don’t forget to source control your automated tests too.

Use an IDE

An IDE (Integrated Development Environment) will pay back in the long run.  When I am compiling, the error log created contains links to the offending code.  When I create a new Java class, I use templates to initially set up the class.  When I am starting up a new project, the IDE organizes it to make it easy to deploy.  Good ones are expandable so I can create a tool to help me create a solution if one hasn’t been created already.  I have been using Eclipse lately and the amount of add-ons it has blows me away.  I can install servers on my computer and Eclipse will start up and shutdown the server as needed.  It automatically builds source code so I know exactly where the code doesn’t compile before I do a test.

Well, there is my quick list.  If you can think of anything else, post a comment.

Links

www.eclipse.org

www.googlecode.com

Advertisement

Using the Java Naming and Directory Interface (JNDI) (Part 2)

In my last post, I discussed directory servers and a quick example of how to query them. To read part one click here. JNDI can be used to store whole objects into a LDAP server. In this entry, a java object will be stored on the server directly.

First example uses a mechanism that Java has had since the beginning, serialization. I need to define a user class. The following class is from User.java:

public class User implements Serializable {

private static final long serialVersionUID = 3999866113934116781L;

private String name;

private String userid;

private String email;


public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getUserid() {

return userid;

}

public void setUserid(String userid) {

this.userid = userid;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

}

It is just a number of setters and getters for a name, user id and email. It does implement java.io.Serializable to make it work for storage. Here is the class that uses User.java.

public class JavaObjectLookup {

static Hashtable<String, String> getEnv() {

Hashtable<String, String> env = new Hashtable<String, String>();

env.put(Context.INITIAL_CONTEXT_FACTORY, “com.sun.jndi.ldap.LdapCtxFactory”);

env.put(Context.PROVIDER_URL, “ldap://localhost:10389/ou=java,dc=example,dc=com”);

return env;

}

public static void main(String[] args) {

DirContext ctx = null;

try {

ctx = new InitialDirContext(getEnv());

// first bind an object to the Directory

User user = new User();

user.setName(“Joey”);

user.setUserid(“joey”);

user.setEmail(“joey@example.com”);


ctx.bind(“cn=joey”, user);


User u = (User)ctx.lookup(“cn=joey”);


System.out.println( “User’s email is “ + u.getEmail());

} catch (NamingException e) {

e.printStackTrace();

}

finally {

try {

ctx.close();

} catch (Exception e) {

e.printStackTrace();

}

}

}

}


Notice that the connection URL has been changed to “ou=java,dc=example,dc=com” so the object will be put into the java organizational unit. On the LDAP server, the entry looks like the following:

dn: cn=joey,ou=java,dc=example,dc=com

objectClass: javaSerializedObject

objectClass: javaObject

objectClass: javaContainer

objectClass: top

cn: joey

javaClassName: org.mathison.example.jndi.User

javaSerializedData:: rO0ABXNyAB5vcmcubWF0aGlzb24uZXhhbXBsZS5qbmRpLlVzZXI3gmE

J1ipHrQIAA0wABWVtYWlsdAASTGphdmEvbGFuZy9TdHJpbmc7TAAEbmFtZXEAfgABTAAGdXNlcm

lkcQB+AAF4cHQAEGpvZXlAZXhhbXBsZS5jb210AARKb2V5dAAEam9leQ==

javaClassNames: org.mathison.example.jndi.User

javaClassNames: java.lang.Object

javaClassNames: java.io.Serializable

The instance is stored as a base-64 encoded string. This is good for storing an instance that a lot of different java processes will access such as a printer driver. But what if a service wants to register its services on a LDAP server? It is no good to store a copy of a service on a directory server because a service is only useful if it can serve. It would be better if the entry just “referred” at the service rather being a copy of it. This is the rational for using javax.naming.Reference. To store a reference, a developer can have the class implement java.naming.Referenceable and call bind on the object or create a reference and bind the reference. On retrieving the reference, a developer can create an object from the information in the reference instance. If an object factory is used, the lookup returns an instance of your class. The following example has ReferUser that implements Referencable and uses an object factory.

Example code:

public class JavaObjectRefLookup {


static Hashtable<String, String> getEnv() {

Hashtable<String, String> env = new Hashtable<String, String>();


env.put(Context.INITIAL_CONTEXT_FACTORY, “com.sun.jndi.ldap.LdapCtxFactory”);

env.put(Context.PROVIDER_URL, “ldap://localhost:10389/ou=java,dc=example,dc=com”);


return env;

}

/**

* @param args

*/

public static void main(String[] args) {

DirContext ctx = null;

try {

ctx = new InitialDirContext(getEnv());


// first bind an object to the Directory

ReferUser user = new ReferUser();

user.setName(“Joey”);

user.setUserid(“joey”);

user.setEmail(“joey@example.com”);


ctx.rebind(“cn=joey”, user);


ReferUser u = (ReferUser)ctx.lookup(“cn=joey”);


System.out.println( “User’s email is “ + u.getEmail());

} catch (NamingException e) {

e.printStackTrace();

}

finally{

try {

ctx.close();

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

import org.mathison.jndi.example2.User;

public class ReferUser extends User implements Referenceable {

public Reference getReference() throws NamingException {

Reference ref = new Reference(this.getClass().getName(),

ReferUserFactory.class.getName(), null);

ref.add(new StringRefAddr(“name”, getName()));

ref.add(new StringRefAddr(“mail”, getEmail()));

ref.add(new StringRefAddr(“uid”, getUserid()));

return ref;

}

}

import javax.naming.directory.Attributes;

import javax.naming.spi.DirObjectFactory;

public class ReferUserFactory implements DirObjectFactory {

@Override

public Object getObjectInstance(Object arg0, Name arg1, Context arg2, Hashtable arg3, Attributes arg4) throws Exception {

return getObjectInstance(arg0, arg1, arg2, arg3);

}

@Override

public Object getObjectInstance(Object arg0, Name arg1, Context arg2, Hashtable arg3) throws Exception {

ReferUser user = null;

if (arg0 instanceof Reference){

Reference ref = (Reference)arg0;

if(ref.getClassName().equals(ReferUser.class.getName())) {

RefAddr name = ref.get(“name”);

RefAddr uid = ref.get(“uid”);

RefAddr email = ref.get(“mail”);


user = new ReferUser();

user.setName(name.getContent().toString());

user.setEmail(email.getContent().toString());

user.setUserid(uid.getContent().toString());

}

}

return user;

}

}

Here is what you will find if you take a look at the Directory Server:

dn: cn=joey,ou=java,dc=example,dc=com

objectClass: javaContainer

objectClass: javaNamingReference

objectClass: javaObject

objectClass: top

cn: joey

javaClassName: org.mathison.example.jndi.ReferUser

javaFactory: org.mathison.example.jndi.ReferUserFactory

javaReferenceAddress: #0#name#Joey

javaReferenceAddress: #1#mail#joey@example.com

javaReferenceAddress: #2#uid#joey

Notice that the object’s attributes are now stored in javaReferenceAddress attributes. Also notice how each of these techniques used special java storage attributes to the job done. Well, the next part of this blog series will tackle creating a object without special java structures. All of this code can be downloaded from https://github.com/darylmathison/jndi-example via subversion or your browser.