We’re All So Young

While I was in Malaysia last year I had several interesting conversations with some of my wife’s siblings.  One in particular has stuck in my mind.

Ahbi and I were at a mamak stall near the house enjoying a late lunch of roti telur and teh tarik.  A mamak stall is an open air restaurant run by Malaysian Indians.  Often the seating is in a parking lot or field that’s just been cordoned off with chairs or planters.  Sometimes it’s in a courtyard or under a structural roof like a pole barn or a lanai.  This particular one was really nice; it was mostly indoors, with two of the walls open.  Roti telur is a buttery flatbread with a scrambled egg cooked into it served with dal, sambal or curry.  You can also get it served with condensed milk or sugar, which Ahbi and I both enjoy sometimes.  And teh tarik is a sweetened black milk tea.

We were talking about how much we had both changed since the last time we’d seen each other.  I’ve always found it interesting that I am such a different person now than I was before.  “Before” can be almost any number of years earlier, and “now” can be pretty much any given moment in time.  Yet no matter when the “now” is, I can always point at some situation in my life or some behavior and say, “I would not have done that back then,” or “I would have handled that completely differently then.”  In fact, my behavior is sometimes so very different that it boggles my brain that I have a sense of “me” with that other strange and foolish person I used to be.  And I know that at some point in the future, this person that I am now will be associated with some other, better, different person who also has a sense of “me” linking the two of us together.

When I get my brain wandering down this path I almost always start lamenting about how by time I figure out how to be a good person at some stage in my life, my life has moved on and now I’m in some other stage bumbling around and being an idiot again.  I am continuously improving, I think, and I am happy with my improvements as well as embarrassed by how rough, crude or stupid I used to be.  But now, as I’m zipping through my midlife, I’m also very aware that I will be my best right around the time my endgame is playing out.  And that makes me sad, not because I’ll die — we all die — but because if I could have been this future Good Person sooner, I could have lived my life so much differently and grown so much more.

Really, 100 years just isn’t very long to figure much out, to do very much, to complete very much.

We’re so conditioned to see 80-100 year olds as being frail, tottery and often demented people who can’t look after themselves anymore.  Of course, we all know that’s just the body breaking down.  How would it be if we could apply all our experience and knowledge, all our growth, and our projects to another few hundred years?  Perhaps if our lifespan was a bit longer, we would be wiser as a species and as a culture.  I would like to think that the self-improvements and gained life experiences of a 300 year old would lend itself to much wiser decision making than that of a 60 year old.

And if we, as an entire species, were making wiser and neccessarily longer-term decisions, there is the potential that everything would be better. 

Some Time In Malaysia

A few of my coworkers have been complaining that I haven’t posted any pictures of our trip to Malaysia this year.  So, here y’all are.  Pics!

Home » Some Time In Malaysia » Travel » Malaysia 2013

Garden

The garden just outside where I usually work.

Garden

Garden

The garden out the other window, from inside, with the bars and laundry and all; typical Malaysia.

Garden

Garden

The garden during a rather fierce rainstorm.

Garden

Freight Scooter

A gas canister on a delivery bike. These guys carry anything and everything on those little 150cc bikes.

Freight Scooter

Stall

A stall with seating. This one is in Penang, famous for it’s Asam Laksa. Apparently the building this stall was in is a short cut to somewhere. We kept getting scooters coming through between us and that cluster of people in the background.

Stall

Temple

Us in Penang at the temple up on the mountainside. Torino suddenly found something more interesting than the camera. Yap, he’s gonna have attention issues just like his papa.

Temple

Vista

Penang from the temple up on the mountainside. That’s George Town in the distance. Closer in is Air Itam.

Vista

Temple

Torino with Poh Poh (Grandma) and Gon Gon (Grandpa) in Penang at the temple up on the mountainside. He’s become such a ham for the camera.

Temple

Torino

Torino had a crush on one of the little statuete animals at the temple.

Torino

Stall

Wifey with her mom and her mom's husband having coconut water at a stall.

Stall

Freight Scooter

This is a food cart, like a food truck, except on the back of one of those little 150cc bikes.

Freight Scooter

No Durian

The ubiquitous “No Durian” sign. Durian is a local fruit that some people like to eat. It’s extremely smelly, by which I mean, “It stinks to high heaven.” Most hotels ban it.

No Durian

Architecture

It’s common to see shiny new buildings next to old dilapitated, run down, moldy structures like this. This was in Penang.

Architecture

Stall

Another stall. This one doesn’t have it’s own seating, but since we were there on a lazy Saturday morning, they had tables set up in the parking lot for the auto shop next door. This is Torino and Poh Poh (Grandma).

Stall

Teh Tarik

Teh Tarik (pulled milk tea) at another stall with seating. This is my favorite morning drink. Torino with Mama.

Teh Tarik

Drain

The gutters on the side of the road are usually open and deep. They get astounding flash-floods there sometimes (and this from a guy living in central Texas).

Drain

Beef Balls

The juvenile delinquent in me.

Beef Balls

Ice Guy

This guy was cutting and delivering ice from the back of a peddle-pulled bicycle cart. They use the ice to make these shaved ice desserts with Asian things in them, like red beans and slimy green jellies.

Ice Guy

Village

This is a village in Penang. This is one of the common village styles. Ha! I say “style” like it’s planned or something. It’s just a low row of shops all hawking wares and foodstuffs.

Village

Stall

A typical restaurant. It’s more like a stall with seating. Most of our meals are at places like this.

Stall

Monkey

A monkey eating a banana.

Monkey

Monkey

A monkey eating Dosai.

Monkey

Monkeys

Torino wanted to play with the monkeys, but we wouldn’t let him. We’re big meanies.

Monkeys

Exploring

Torino and The Daddyman (that’s me) found a secret path with a cool stone arch. The monkeys avoided this area for some reason which we never determined.

Exploring

Resolving servletContext.contextPath Expression in Spring 3.2

I ran into a painful thing with Spring 3.2 trying to reference the deployed servlet’s contextPath from within the web dispatch context.  I thought it would be good to write up my notes in case anybody else runs into a similar problem.

I have a case where I want the same web application to execute side-by-side on the same server.  I deploy the app into differently named contexts depending on the focus of that app.  For example, myapp-trees, myapp-bushes, and myapp-plants.  I need different configurations for each of the contexts in order for them to work properly.

So, my thought was to use the contextPath to find the correct properties file in the spring web dispatch context file.  Something like this:

<context:property-placeholder location="classpath:${servletContext.contextPath}.properties"/>

That doesn’t work for a whole slew of reasons.  First and foremost, in Spring 3.2 there is no longer a variable servletContext namespace.  Instead, it’s been replaced with servletContextInitParams.  That seems like a silly and arbitrary access constraint to me, but I haven’t heard the pros and cons around this decision.

My initial solution attempt was to extend the ServletContextEnvironment to push the servletContext into the resolution chain. 

Here’s the ServletContextEnvironment:

public class ServletContextEnvironment
  extends StandardServletEnvironment
  implements ServletContextAware
{
  /** Servlet context property source name: {@value} */
  static public final String SERVLET_CONTEXT_SOURCE_NAME = "servletContext";
  @Override
  public void setServletContext (ServletContext servletContext)
  {
    _log.debug("Setting servletContext");
    _servletContext = servletContext;
    initServletContextSource();
  }
  @Override
  protected void customizePropertySources (MutablePropertySources propertySources)
  {
    // set a stub now, replace it later when we have the servletContext
    propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_SOURCE_NAME));
    super.customizePropertySources(propertySources);
  }
  @Override
  public String getProperty (String key)
  {
    _log.debug("getProperty " + key);
    return super.getProperty(key);
  }
  protected void initServletContextSource ()
  {
    MutablePropertySources propertySources = getPropertySources();
    if (_servletContext != null &&
        propertySources.contains(SERVLET_CONTEXT_SOURCE_NAME) &&
        propertySources.get(SERVLET_CONTEXT_SOURCE_NAME) instanceof StubPropertySource)
    {
      propertySources.replace(SERVLET_CONTEXT_SOURCE_NAME,
          new ServletContextSource(SERVLET_CONTEXT_SOURCE_NAME,_servletContext));
    }
  }
  private ServletContext _servletContext;
  private Logger _log = LogManager.getLogger(getClass());
}

And the ServletContextSource that it inserts into the environment:

public class ServletContextSource
  extends PropertySource<ServletContext>
{
  public ServletContextSource (String name, ServletContext source)
  {
    super(name, source);
  }
  @Override
  public Object getProperty (String name)
  {
    if (name.startsWith(getName()))
    {
      name = name.substring(getName().length() + 1);  // + 1 for the "."
      _log.debug("Resolving " + name);
      if (name != null)
      {
        String caseName =
            (name.length() > 0 ? name.substring(0,1).toUpperCase() : "") +
            (name.length() > 1 ? name.substring(1) : "");
        String[] prefixes = { "get", "is", "has" };
        for (String prefix: prefixes)
        {
          try
          {
            Method getter = getSource().getClass().getMethod(prefix + caseName);
            return getter.invoke(getSource());
          }
          catch (NoSuchMethodException ignore)
          {}
          catch (InvocationTargetException | IllegalAccessException e)
          {
            _log.warn("Could not get property " + name + ": " + e.toString());
          }
        }
      }
    }
    return null;
  }
  private Logger _log = LogManager.getLogger(getClass());
}

However, this still doesn’t allow me to do the above because the resolution of the ${} variable in the location attribute happens before my custom ServletContextEnvironment is hooked into the placeholder resolution chain.  “Pow!” right to the face.

So, I adjusted my attack vector a bit.  I put all my properties in a single properties file, prefixing the ones for each environment with the context path for that environment.  For example:

/myapp-trees.update-schedule=0 5 23 * * MON
/myapp-shrubs.update-schedule=0 5 23 * * TUE
/myapp-plants.update-schedule=0 5 23 * * WED

Notice that slash in the front?  Yeah, that annoys the piss outta me.  The context path returned by the ServletContext object includes that, so it has to be part of the property name.  It’s entirely possible to hack something in that will remove that, of course.

So then, in my bean definitions, I referenced the properties with a nested reference to the servletContext.contextPath, like so:

<property name="cronExpression" value="${${servletContext.contextPath}.update-schedule}" />

Great!  Since I already have the code to inject the servletContext resolutions, that solves everything, right?  Not so fast there, Skippy.

It seems that Spring 3.2 has a feature by which any environment set in the PropertySourcesPlaceholderConfigurer will be overwritten with their own StandardServletEnvironment.  “Bam!” right to the face.

To solve this, I extended the PropertySourcePlaceholderConfigurer and overrode the setEnvironment method with a setter that would only set it if it hadn’t already been set.  Seems straightforward, right?  Well, there’s a problem with that: there is no getEnvironment method, and the environment member defined by the parent class is scoped as private.  So there’s no way to tell if the environment has been set.

So, I set the subclass to track it’s own environment member.  That meant I had to override every method that used the environment in the parent class so that it would use my environment instead.

On the one hand it would have been easier to just patch the parent class.  It would have been a 1 line change.  On the other hand, then I’d be stuck in the world of building my own version of the spring jars.  That’s not a fun world.

Here’s my subclassed Configurer:

public class EnvironmentPropertySourcesPlaceholderConfigurer
  extends PropertySourcesPlaceholderConfigurer
{
  @Override
  public void setEnvironment (Environment environment)
  {
    if (_environment == null)
    {
      _log.debug("Setting environment " + environment.toString());
      _environment = environment;
    }
    else
    {
      _log.debug("Ignoring environment override request " + environment.toString());
    }
  }
  @Override
  public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory)
      throws BeansException
  {
    MutablePropertySources sources = new MutablePropertySources();
    if (_environment instanceof AbstractEnvironment)
    {
      MutablePropertySources envSources =
          ((AbstractEnvironment) _environment).getPropertySources();
      for (PropertySource envSource: envSources)
      {
        _log.debug("Wiring source " + envSource.getName());
        sources.addLast(envSource);
      }
    }
    try
    {
      PropertySource<?> localPropertySource =
          new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
      _log.debug("Wiring source " + localPropertySource.getName());
      sources.addLast(localPropertySource);
    }
    catch (IOException e)
    {
      throw new BeanInitializationException("Could not load properties", e);
    }
    processProperties(beanFactory, new PropertySourcesPropertyResolver(sources));
  }
  private Environment _environment;
  private Logger _log = LogManager.getLogger(getClass());
}

And the Spring bean definitions for this, which replace the <context:property-placeholder…/> tag:

  <bean class="com.xephyrus.tools.spring.EnvironmentPropertySourcesPlaceholderConfigurer">
    <property name="location" value="classpath:myapp.properties"/>
    <property name="environment">
      <bean class="com.xephyrus.buddy3.tools.spring.ServletContextEnvironment"/>
    </property>
  </bean>

Now it works.

SUP Board Rack Refactoring

One of my Stand-Up Paddleboard racks ripped out of the garage wall a few days ago.  Only one of the four anchors ripped out, so thankfully the board didn’t fall onto the truck.

SUP Rack SUP Rack

That anchor was already a bit weak because I had accidentally pushed down on it once when I was moving the board around.  And none of these anchors were in studs.  I was using 60 lb wall anchors just in the sheetrock.  Really, when you consider that sheetrock is just a bunch of compressed gypsum sandwiched between heavy sheets of paper, it’s pretty amazing this thing held anything at all.  Then we had a few days of rain during the summer.  My guess is the warmth of the summer and moisture of the rain made for a nice humidity that softened the sheetrock just enough more for it to let loose.

Anyhow, so now on to the repair job.  Clearly this whole wall anchor thing isn’t a good idea for SUP boards.  So I decided to put 2×4 cross pieces between the beams and mount the rack struts to that.

I used a studfinder, then measured, then measured again.  Then I used a rotary tool to cut a line to where I thought the beams were.  And they were there.  So I traced the outline of the 2×4 pieces I had cut and used the rotary tool to cut out the sheetrock.

Ripping Into the Wall Board Slots

I predrilled, then used 2 1/2 inch wood screws to attach the 2x4s to the studs.  I stripped out a few of the wood screws in the process.  I guess my drill bit wasn’t long enough, so the screws bound a bit too tight.  They’re ugly and they’ll be hard to work with later if I ever have to do anything with them, but I got them all in.  To hide the ugly and the roughness of the wood, I folded pieces of rubberized shelf liner over the new cross-pieces.

Crosspieces Crosspieces Covered

Then I put the rack struts back on and plunked the board back on it.  It sticks out about an inch further than it did before.  It was already a tight fit getting the truck in without having the mirrors scrape the board, so now it’s going to be 1 inch tougher.  But it’s a way more solid rack now.

Newly Mounted Rack and Board

Brewers Log Moved

I moved all my Brewers Log stuff over to a new blog space.  All that stuff is here now:

Gluten-Free, Dairy-Free, Soy-Free Waffles

I’ve been wanting to share some of our favorite gluten-free, dairy-free, soy-free experiments, but many of them just didn’t work out.  Making some of the common American breakfasts for our allergy-boy turns out to be quite challenging.

I’ve managed to come up with a waffle recipe that has been working pretty well, so here’s to that. 

Waffle Recipe:
1 cup gluten-free flour
1/2 cup oat flour
1/4 cup quick oats
3 tablespoons corn starch
2 teaspoons baking powder
1 teaspoon baking soda
1/4 to 1/2 teaspoon salt (your call)
1 cup rice milk
1/4 cup apple cider vinegar
1/4 cup soy-free shortening, melted
Mix the drys together.
Mix the wets together.
Mix the drys and the wets together.
Cook and eat.
  • If you need extra moisture use rice milk, NOT water.  The texture should be on the runny side, thinner than for pancakes.
  • Keep the waffle iron on the highest setting.  The darkness will depend on the type of gluten-free flour you’re using.  Some flours will take a lot longer to darken than others.
  • If you’re having problems with it sticking, try different rice milk.  For a sticky batch, make the waffles smaller.  If you still can’t make it work, make pancakes out of them.  😛
  • Additives like banana, apple sauce, chocolate chips, etc will encourage the waffles to stick.

Torino’s Allergies

Torino has had eczema almost from the day he was born.  He gets rashes on his neck, on the inside of his elbows and on the inside of his knees.  He has also had reactions from meals a few times where his skin becomes angry and inflamed from mid-chest all the way up to his chin.We were able to get a couple allergy tests done for him, and have discovered that he’s allergic to many of the things our modern food is made from.  He is moderately to severely allergic to: Eggs, Milk, Wheat, Soy, Peanuts and Sesame.

Torino's Rash
Poor guy.

So, now wifey and I are on a mission to make good foods that don’t contain those things.  Luckily wifey is an amazing chef.

The Nursery

We finally got Torino’s nursery decorated and set up, and Torino moved into it.

We did a jungle theme.  We got lots of animal wall stickers and decals and wha-lah.  The Cornell grandparents sponsored about half of them, bless their hearts.

Some various random notes:

  • There is a whole zoo’s worth of animal heads peeking from around the closet door and the window.
  • The birds on the branch by the door are all funky jazz birds.
  • The net hammock in the corner above the closet has 2 keep-sake stuffed animals that were made from Topher’s baby quilt, which was hand-made by Topher’s grandmother when he was a wee one.
  • All Torino’s toys are in a cool giant caterpillar hamper (which you can’t see in any of the pictures).
  • The monkey face rug is actually a bathmat.
  • There are over 100 decals in this room.
  • One of Torino’s favorite stickers is the “consumer safety” sticker on the end of his crib.

I think Serene secretly wishes our room were decorated with cartoon animal heads and monkeys swinging on vines too.

Once we got all the furniture in it suddenly looked much smaller, but also quite warm and cozy.

img_8840_sm.jpg
img_8841_sm.jpg
img_8843_sm.jpg
img_8844_sm.jpg
img_8847_sm.jpg
2012-10-14_13-20-52_436.jpg
2012-10-14_13-30-30_958.jpg
img_8837_sm.jpg
img_8838_sm.jpg
img_8839_sm.jpg

Torino, The Level 1 Human

Serene’s brother sent us this epic baby onesie.  So it only made sense to pull out my good set of dice and a big hex map so we could throw him into a rambunctious campaign.  He loved it, of course; he is my son after all.

img_8093-92-sm.jpg
img_8095-92-sm.jpg
img_8100-92-sm.jpg
img_8103-92-sm.jpg
img_8150-92-sm.jpg
img_8073-92-sm.jpg
img_8077-92-sm.jpg
img_8093-92-sm.jpg
img_8095-92-sm.jpg
img_8100-92-sm.jpg

Wasp Balls

We got wasp balls!

Our new house has two lovely baby Live Oak trees in the front yard.  We noticed these little berry-like balls growing off the bottom of the leaves.

Wasp Balls
Wasp Balls

After trolling the interwebs, I’ve learned that these are called galls.  Apparently certain types of wasps think Oak trees are nice secure places to lay their eggs.  They inject each egg into the leaf, and the tree then responds by creating a protective ball around the egg.

Apparently this is harmless to the tree, other than possibly causing the leaf to deform.  It just freaks out the owner.

References: