Two Guys Arguing

Programming Anti-Patterns: Releasing Cthulhu

Posted in Uncategorized by benjaminplee on 11.10.10

Some code is elegant.  Some code is a quick fix hack.
Some code is maintainable.  Some code release Cthulhu.

These are just a few gems I have found over the past year or so…

 

Math is for the Weak Pattern

if(result == 1) {
    obj.foo(0);
}
else if(result == 2) {
    obj.foo(1);
}
else if(result == 3) {
    obj.foo(2);
}
else if(result == 4) {
    obj.foo(3);
}

Subtraction is a poor abstraction;


Scare the Next Guy Pattern

// ... Base DAO containing transaction logic for whole application ...
if(connection.isOpen()) {
   aSimple.MethodCall();

    // TODO:
}
// ... more complex TX logic ...

Because, what he doesn’t know … might be nothing … or might be something


Decoy Security Pattern

<pre>public Connection getNewConnection() {
    Long.Full.Package.Name.Connection c = new Long.Full.Package.Name.Connection();

    return new Long.Full.Package.Name.Connection();
}

No cups in this shell game, just database connections


Missing Father Pattern

try {
    foo.bar();
}
catch(Exception e) {
    throw e;
}

If dad is never around, you end up playing catch with yourself

All codes have been modified and rewritten to protect the guilty.
Tagged with:

Start Tomcat from the REPL

Posted in Uncategorized by youngnh on 11.10.10

One of the first things that I wrote in Clojure was a few files that launched a tomcat server from a repl. My code was separated into 3 files:

  • tomcat.clj created a Tomcat server through the Embedded class, which you could then start and stop from the repl
  • tomcat_loader.clj which handled separating classloaders for tomcat itself and the webapps deployed to it
  • classloading.clj which held generic utility functions for creating class loaders and searching file paths

Creating an embedded tomcat engine is an excercise in Clojure-Java iterop:

(defn create-embedded-tomcat [#^String hostname app-base contexts]
  (let [embedded (Embedded.)
        engine (.createEngine embedded)
        host (.createHost embedded hostname app-base)
        http-connector (.createConnector embedded hostname 8080 "http")
        ssl-connector (.createConnector embedded hostname 8443 true)]
    (.setParentClassLoader engine tomcat-shared-loader)
    (doall (map #(% embedded host) contexts))
    (.addChild engine host)
    (.addEngine embedded engine)
    (.addConnector embedded http-connector)
    (.addConnector embedded ssl-connector)
    embedded))

app-base is a file path from which Tomcat will serve webapps out of, it’s webapps/ in the standalone distribution, but creating your own engine, you can now set it to anywhere you’d like. contexts is a list of Context objects, applications that you want Tomcat to serve that might not be in the app-base folder. I wrote a helper fn to create then:

(defn context [path war-file]
  (fn [embedded host]
    (let [context (.createContext embedded path war-file)]
      (.addChild host context))))

(context "/myapp" "/home/awesomesauce/dinosaur-app.war")

The Embedded object that create-embedded-tomcat returns has .start and .stop methods on it, so no need for special Clojure fns for them, just invoke the methods directly on the object.

The classloading magic happens in tomcat.clj‘s ns header. It :uses tomcat_loader.clj which creates 3 classloaders:

(def thread-context-loader (.. (Thread/currentThread) getContextClassLoader))

(def tomcat-common-loader (create-class-loader (expand-paths tomcat-common-path) thread-context-loader))
(def tomcat-catalina-loader (create-class-loader (expand-paths tomcat-catalina-path) tomcat-common-loader))
(def tomcat-shared-loader (create-class-loader (expand-paths tomcat-shared-path) tomcat-common-loader))

Each of these class-loaders are created via create-class-loader which takes a “loader-map” and a parent classloader to create a URLClassLoader. The 3 “loader-maps” are specified like so:

(def *catalina-home* (or (System/getProperty "catalina.home") (System/getProperty "user.home")))

(def tomcat-common-path 
     {*catalina-home*
      {"common/classes" :dir
       "common/i18n/" :glob
       "common/endorsed/" :glob
       "common/lib/" :glob}})

(def tomcat-catalina-path 
     {*catalina-home*
      {"server/classes" :dir
       "server/lib/" :glob}})

(def tomcat-shared-path 
     {*catalina-home*
      {"shared/classes" :dir
       "shared/lib/" :glob}})

So they’re simple maps that specify where to find jars and class files on the system. With this hierarchy of classloaders set up, Clojure then has the means to find the classes it needs when we ask it to instantiate a Tomcat server.

I haven’t run this code in a while and it’s getting late, but when I get a chance, I’ll scrub it and run it through it’s paces and post it somewhere you can get your hands on it.