Undirected Ramblings

Thoughts on culture, technology, and anything else that comes to mind.

Available categories: [/] [Entertainment] [Linux] [Meta] [General Miscellany] [Politics] [Technology] [Java]

Why Tab Indentation is Evil [Permalink]

Tue Dec 11 16:48:32 EST 2007
Category [Java]

Tab indentation is Wrong. I know this instinctively, but from time to time I forget the actual proof of this and go looking around on the interwebs, only to find a bunch of religious-warlike opinions that are mostly subjective. Yesterday I remembered the Real Reason why tab indentation is objectively horrible. Here we go: tab stops differ between systems, so tab indentation is shown with varying amounts of white space, depending on the system on which the file is displayed. In order to properly indent code, one sometimes (often) needs to indent to a position that does not fall on a tab stop. One example is this:

public Person findPerson(String firstName,
                         String lastName,
                         String zipCode);
In order to line up the arguments with the open paren, an editor using tab indentation is then forced to use a combination of tabs and spaces that is correct only when viewed with tab stops set to the same increment as that on the computer creating the file, thus making the argument that different people viewing code on different machines can use indentation steps to their liking completely invalid. Tab indentation is simply broken for code such as this. I just don't understand why an editor like Eclipse would make tab indentation the default. I've seen so much unreadable code as a direct result of this, it's not funny. Please! For the sake of good taste and human decency, stop using tab indentation! Thank you.

Comments [0] | Trackbacks [0]

Chasing Methods With Interfaces in Eclipse [Permalink]

Wed Jan 24 20:19:43 EST 2007
Category [Java]

Back in the days when I was doing software development full time for one company, we had a few arguments about the relative merits of designing by interface. The product we happened to work on had almost certainly overused interfaces, with nearly a 1:1 relationship of interface to class. It didn't help that they named things horribly, calling the interfaces along the lines of SomeObjectIxf, with the corresponding implementation being SomeObject. (Interfaces are your contract/service, the word you're using when you talk about that component of your application!)

Anyway, one of the main objections to using interfaces when you only have one implementation of an object is that it makes code much more difficult to trace in Eclipse, since when you control-click the method name, Eclipse goes to the interface instead of the object you're looking for. This means you'd have to separately find the implementer of that class, then navigate to that class, remembering which method you were trying to trace, then navigate to the method. Today I learned an easier way. To trace a method through to its implementer from a call on an interface, simply click on the method (no need to highlight, as long as the cursor is in the method name) and type control-t. This will display the type hierarchy of the interface on the page, and then you can down arrow to the implementing classes and hit return. Eclipse will take you to the right method in the implementing class. It's still one step more difficult than just control-clicking, but effectively makes it almost trivial to trace methods, even through calls on an interface.

Comments [0] | Trackbacks [0]

Become One with the OBEX [Permalink]

Thu Dec 14 23:19:30 EST 2006
Category [Linux]

For some reason possibly related to the fact that I've just started traveling almost full time and didn't bring along a real camera, I decided to figure out how to wheedle files away from my RAZR onto my Linux laptop over the bluetooth airwaves. It's very simple:

obexftp -b 00:15:A8/images/emoticons/grin.gif7:82:E7 -l /picture|grep file \
  |awk -F \" ' {print "/picture\/"$2;}'|xargs obexftp -b 00:15:A8/images/emoticons/grin.gif7:82:E7 -g

What? That doesn't look simple? The "-b" option in both invocations of obexftp must be your phone's device ID. The "-l" option tells obexftp to list the files on the device, then we munge around the output to get the filenames, and ask obexftp to get them with a "-g" option. Yay! Now I can marvel at the impressively low quality photos produced by my phone.

Comments [0] | Trackbacks [0]

Not a Wuss, After All [Permalink]

Tue Dec 05 23:45:20 EST 2006
Category [General Miscellany]

Today, day 2 of my new job with Interface21, was spent at the Islands of Adventure theme park in Orlando, Florida. I've never been a big fan of roller coasters, and before today I think I've been on a full-scale roller coaster exactly once in my life. The idea of intentionally placing myself in a situation where I was practically guaranteed to have the crap scared out of me just never seemed particularly appealing. Today, however, the combination of opportunity and peer pressure placed me in the position of riding not one, but three (3) roller coasters in one day. I returned for a second ride on two of them, and I have to say that I actually enjoyed the rides, despite being left with a somewhat queasy and out-of-balance feeling each time. They're quite an adrenaline rush, and it's kind of interesting to see what sorts of psychological tricks and acrobatics they can put you through in order to get your blood flowing. The Dueling Dragons coaster was particularly exciting, a ride in which you are suspended from above and twirled around in the air upside down and right side up and around and around, almost running into a second car of passengers, from which you turn away at the last moment. I think my head is still spinning a bit from being thrown around so much.

Tomorrow we head down to Hollywood, just north of Miami, for The Spring Experience. I'm excited to be attending what promises to be a dizzying array of sessions all about Spring. Being in a fancy hotel on the beach shouldn't hurt either, but I'm really most excited by meeting all the Spring luminaries with whom I will now be working, and learning a lot along the way. I've got a good week ahead of me!

Comments [0] | Trackbacks [0]

Fun with Linux Routing [Permalink]

Sat May 20 21:49:25 EDT 2006
Category [Java]

I tried running the import program for my photo application today, which parses an XML file with a DTD. It failed with "java.net.ConnectException: Connection refused." This was a bit baffling to me, since the DTD in the document was hosted on the same server that I was running the program. A quick check with netcat confirmed that, in fact, connections were being refused on port 80 to the same host. Even more baffling was that I was still serving web requests to outside hosts with no trouble.

Anyway, to make a long story short, the trouble turned out to be in my routing configuration, which is setup to redirect port 80 to port 8080 and port 443 to 8443 so that I can run Resin as an unprivileged user while still responding to requests on port 80. I had never paid particular attention to the specifics of the common advice I had found on the web (I think in Caucho's documentation, actually) except to note that it worked. My previous routing rules were these:


    iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j REDIRECT --to-port 8080 -d 66.92.72.224
    iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j REDIRECT --to-port 8080 -d 66.92.72.225
    iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth1 -j REDIRECT --to-port 8080 -d 66.92.72.224
    iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth1 -j REDIRECT --to-port 8080 -d 66.92.72.225
    iptables -t nat -A PREROUTING -p tcp --dport 443 -i eth0 -j REDIRECT --to-port 8443 -d 66.92.72.224
    iptables -t nat -A PREROUTING -p tcp --dport 443 -i eth0 -j REDIRECT --to-port 8443 -d 66.92.72.225
    iptables -t nat -A PREROUTING -p tcp --dport 443 -i eth1 -j REDIRECT --to-port 8443 -d 66.92.72.224
    iptables -t nat -A PREROUTING -p tcp --dport 443 -i eth1 -j REDIRECT --to-port 8443 -d 66.92.72.225

There are two problems with this. First, the PREROUTING chain seems only to affect packets actually routed by the box, so not locally originated packets. I fixed this by adding a set of similar rules in the OUTPUT chain, which affects packets before routing. From the iptables man page:

            nat:
                  This table is consulted when a packet  that  creates  a  new
                  connection  is encountered.  It consists of three built-ins:
                  PREROUTING (for altering packets as soon as they  come  in),
                  OUTPUT  (for altering locally-generated packets before rout‐
                  ing), and POSTROUTING (for  altering  packets  as  they  are
                  about to go out).

The new lines looked like this:

    iptables -t nat -A OUTPUT -p tcp --dport 80 -i eth0 -j REDIRECT --to-port 8080 -d 66.92.72.224
    iptables -t nat -A OUTPUT -p tcp --dport 80 -i eth0 -j REDIRECT --to-port 8080 -d 66.92.72.225
    iptables -t nat -A OUTPUT -p tcp --dport 80 -i eth1 -j REDIRECT --to-port 8080 -d 66.92.72.224
    iptables -t nat -A OUTPUT -p tcp --dport 80 -i eth1 -j REDIRECT --to-port 8080 -d 66.92.72.225
    iptables -t nat -A OUTPUT -p tcp --dport 443 -i eth0 -j REDIRECT --to-port 8443 -d 66.92.72.224
    iptables -t nat -A OUTPUT -p tcp --dport 443 -i eth0 -j REDIRECT --to-port 8443 -d 66.92.72.225
    iptables -t nat -A OUTPUT -p tcp --dport 443 -i eth1 -j REDIRECT --to-port 8443 -d 66.92.72.224
    iptables -t nat -A OUTPUT -p tcp --dport 443 -i eth1 -j REDIRECT --to-port 8443 -d 66.92.72.225

I loaded the rules and in my testing discovered that the host configured on my second IP address, 66.92.72.225, was coming up with the content from the first IP, trailmagic.com, in my browser. I looked over the rules a few more times and, resorting to the man page once again, discovered that the REDIRECT target "redirects the packet to the machine itself by changing the destination IP to the primary address of the incoming interface." Clearly not what I wanted, since I've got two interfaces in this machine and one virtual interface, each configured with a different IP address. A little more studying turned up the DNAT target, which does exactly what I want (and thought REDIRECT was doing earlier). This probably explains why the commonly-recommended rules seem to work for most people, and are still working on my development machine, namely that most people don't have more than one interface, so it doesn't matter that REDIRECT only uses the primary interface. My final rules look like this:

    iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to-destination 66.92.72.224:8080 -d 66.92.72.224
    iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to-destination 66.92.72.225:8080 -d 66.92.72.225
    iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth1 -j DNAT --to-destination 66.92.72.224:8080 -d 66.92.72.224
    iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth1 -j DNAT --to-destination 66.92.72.225:8080 -d 66.92.72.225
    iptables -t nat -A PREROUTING -p tcp --dport 443 -i eth0 -j DNAT --to-destination 66.92.72.224:8443 -d 66.92.72.224
    iptables -t nat -A PREROUTING -p tcp --dport 443 -i eth0 -j DNAT --to-destination 66.92.72.225:8443 -d 66.92.72.225
    iptables -t nat -A PREROUTING -p tcp --dport 443 -i eth1 -j DNAT --to-destination 66.92.72.224:8443 -d 66.92.72.224
    iptables -t nat -A PREROUTING -p tcp --dport 443 -i eth1 -j DNAT --to-destination 66.92.72.225:8443 -d 66.92.72.225


# for local packets
    iptables -t nat -A OUTPUT -p tcp --dport 80  -j DNAT --to-destination 66.92.72.224:8080 -d 66.92.72.224
    iptables -t nat -A OUTPUT -p tcp --dport 80  -j DNAT --to-destination 66.92.72.225:8080 -d 66.92.72.225
    iptables -t nat -A OUTPUT -p tcp --dport 443  -j DNAT --to-destination 66.92.72.224:8443 -d 66.92.72.224
    iptables -t nat -A OUTPUT -p tcp --dport 443  -j DNAT --to-destination 66.92.72.225:8443 -d 66.92.72.225

The DNAT target takes a --to-destination instead of a --to-port and redirects to the specified port on the specified IP address. With the new rules, everything serves correctly to the right ports on the right IP addresses from on or off the server. Problem solved. Maybe next time I'll read the man page before setting up the rules.

Comments [0] | Trackbacks [0]

Maven Repository for Ant [Permalink]

Sat Mar 04 19:56:13 EST 2006
Category [Java]

I recently discovered that the Maven Project has made available some of its tasks for Ant. I've noted previously that Maven's repository feature is quite nice, although I haven't been as attracted to the system as a whole, so this is a great development for those of us using Ant for our build systems. I'll definitely be thinking about integrating this into the build systems I use if I ever get a bit of free time.

Comments [1] | Trackbacks [0]

On Java Web Start and Browsers [Permalink]

Fri Mar 03 17:24:41 EST 2006
Category [Java]

I've been playing around with a few Java Web Start applications lately (most notably the excellent BlogBridge, which I'll likely write about at some point in the future), and one problem I ran into was that, when I clicked on a link to launch in a browser, the link would opoen in the wrong browser. Once I figured out that I could run javaws to bring up preferences and set the browser to Firefox, clicking a link would open a new window, something that in my home is absolutely not tolerated. It appeared that the Web Start software was deciding to add extra arguments to pass to the browser on the command line, to explicitly tell it to open a new window.

Now, I could froth and foam about how many ways this behavior is wrong on the part of Web Start, mainly having to do with ignoring both my GNOME preference for Firefox and my Firefox preference to never open new windows, but I'll spare you my fury. Instead, I'll pass on the workaround I found to solve it. A little bit of searching let me to the conclusion that one can set a property in the deployment.properties file (~/.java/deployment/deployment.properties on Linux) called deployment.browser.args to determine the arguments to pass the browser. All I had to do was add the following line (just below the line that specified the deployment.browser.path), and everything worked perfectly:

deployment.browser.args=%u

The %u means the URL to be passed to the browser, and it seems you're free to add other arguments you'd like to pass. So it looks like this scheme could be used to make any browser work, even if it takes strange and unusual arguments. So in the end, I'm glad Java Web Start provides this configurability. It provides all the flexibility one needs in invoking an external browser. I wish, however, that this had been exposed in the preferences UI, or failing that, explained somewhere more prominently in the documentation (maybe it's there, but my search didn't turn up any official documents).

Comments [1] | Trackbacks [0]

In Association with Amazon.com [Permalink]

Wed Mar 01 15:47:50 EST 2006
Category [Meta]

I just signed up for an Amazon.com Associate account. So now you can click on this here fancy link and buy stuff, and I'll get a commission. Isn't the Internet great?

Comments [0] | Trackbacks [0]

Manglish [Permalink]

Wed Feb 15 16:51:56 EST 2006
Category [Entertainment]

boingboing.net recently pointed me to this guy's site, which features a staggering number of mangled English, or "manglish", as he calls it, appearing on Chinese products and signage. There's some seriously funny stuff in there. "One times chopstick equals chopstick, even for very large values of chopstick" was one of his more amusing comments.

Comments [0] | Trackbacks [0]

Multi-Touch Interaction Research [Permalink]

Wed Feb 15 16:47:02 EST 2006
Category [Technology]

This has got to be one of the coolest things I've seen in a long time. Not only have they come up with a great new technology, they've found a bunch of interesting ways to use it (which they show off in the demo video). The part with the photographs had me drooling.

Comments [0] | Trackbacks [0]

Instant Messaging Gets Serious [Permalink]

Wed Jan 18 12:17:11 EST 2006
Category [Technology]

I spent some time last week testing out a Jabber server at work, and then implemented it this weekend on my own server. Every once in a while I've searched around for a good server, and this time I was immensely pleased to find what seems to be a high quality, open source implementation in Java. The server is Wildfire, which is also a commercial product from Jive Software.

Setting up the server was almost trivial, and consisted of simply running the software on my server, editing a few configuration settings in the easy to use web interface, and following clear instructions for adding my own SSL key with the standard Java keytool. The hardest part was writing an init script, which I think would have been provided, had I used the binary package rather than building from source. The server supports secure messaging via TLS, for both client to server (C2S) and server to server (S2S) connections. The S2S support also means that friends on other Jabber servers, such as jabber.org, can add me to their buddy lists and communicate with me, even though our accounts are managed by other servers. This is one key feature of the Jabber protocol that I think will help it usurp the proprietary protocols and usher in a new era of open communications. A fringe benefit is that my Jabber ID is now the same as my email address.

Once I had a server running at work, I decided that it would be neat to have our build robot output status messages to a persistent developer chat room. The room was easy to setup from the Wildfire administration interface, so my only challenge was to write the software to connect to the Jabber server, enter the chat room, output a message, and leave. As it happens, Jive Software has another product, called Smack, that provides a great interface (again, open source) to the Jabber protocol in Java. A quick download and about 30 lines of code later, I had a running program that, when invoked from the command line, would output its arguments to our developer chat room. This is some good stuff, and the Jive Software folks deserve some serious praise for making this software available as open source.

It just keeps getting better

With my new Jabber server now setup and running smoothly, imagine the joy with which I read yesterday's announcement that Google Talk will now support open federation! While Google is not the first large provider of Jabber service, they do have the clout, name recognition, and finances to really push Jabber ahead in the world. Their support of open federation means that I can tell all my friends to sign up for Google Talk, and they'll be able to talk to me via my account on my own server. Hopefully this will bring a hasty end to the days of having to sign up for 5 different IM accounts just to talk to different friends, and having to use silly insecure protocols that send your messages over the network in the clear, easily intercepted by anyone who can plug in a network cable in the path of their transmission. I am very happy with Google right now.

Comments [0] | Trackbacks [0]

Configuring the Logitech MX 5000 [Permalink]

Wed Jan 18 11:16:10 EST 2006
Category [Linux]

I bought a fancy new Logitech MX5000 the other day, and I thought I'd share my recent success in getting everything working with Linux. The bunndle includes an "MX 5000 keyboard for Bluetooth" and a Bluetooth version of the MX 1000 mouse. I've had the RF version of the MX 1000 working for months now, but the new hardware was just different enough that my old configuration didn't suffice to get everything working correctly. Though both the keyboard and mouse worked out of the box with basic functionality, the fancy buttons and tilt wheel weren't working on the mouse, and it was tracking too fast. I still haven't managed to have them recognized as actual Bluetooth devices (they just show up as USB HID devices), but now all the buttons and tracking are working flawlessly. My old configuration, used with my RF version of the MX1000, didn't recognize the new version of the mouse, yielding errors like "cannot register with evdev brain" in my Xorg log.

The key step in getting everything working was to use the new "evdev" driver, rather than using what appears to have been some sort of hack to include evdev support in older versions of X.org. Here's what my configuration for the RF mouse looked like:

Section "InputDevice"
 Identifier "MX1000"
 Driver     "mouse"
 Option     "CorePointer"
 Option     "Protocol"        "evdev"
 Option     "Dev Name"        "Logitech USB RECEIVER"
 Option     "Buttons"         "12"
 Option     "ZAxisMapping"    "11 12 10 9"
 Option     "Resolution"      "800"
 Option     "Emulate3Buttons" "false"
EndSection

Using the new driver required an upgrade to X.org 6.9.0, after which the configuration looks like this:

Section "InputDevice"
  Identifier    "MX1000"
  Driver        "evdev"
  Option        "CorePointer"
  Option        "Device"        "/dev/input/mx1000"
  Option        "Resolution"      "800"
EndSection

Before we can reference this new /dev/input/mx1000 device, however, we need to make sure that it gets created by udev. I put the following lines in a new file called /etc/udev/rules.d/010_local.rules. It's important that this file be called before any other "event" rules, and that it end with ".rules", so the name is significant. This covers both my RF mouse and the bluetooth version. The bluetooth version needs the extra idProduct specification, as the keyboard and the dongle get registered with the same manufacturer and product name.

KERNEL=="event*", SYSFS{manufacturer}=="Logitech", SYSFS{product}=="Logitech BT Mini-Receiver", \
    SYSFS{idProduct}=="0xc70a", NAME="input/mx1000", mode=="0644"
KERNEL=="event*", SYSFS{manufacturer}=="Logitech", SYSFS{product}=="USB RECEIVER", \
    NAME="input/mx1000", mode=="0644"

On one of my systems, the idProduct value is simply c70a (i.e. without the "0x" at the beginning, so you'll have to poke around in /sys to find out what it says on your system. find /sys -name idProduct|xargs cat should tell you which format it's in on your system.

With these new settings in place, I simply stop and start udev, do the same with Xorg, and everything works perfectly. All the mouse buttons are correctly detected, and vertical and horizontal scroll work flawlessly. To get my thumb buttons working as forward and back buttons in firefox, I added xbindkeys to my .Xclients file (which I've got setup as a startup program in Gnome) and added the following to .xbindkeysrc:

# Backward and Forward buttons
"xvkbd -no-jump-pointer -no-repeat -xsendevent -text "\[Alt_L]\[Left]""
  m:0x10 + b:8
"xvkbd -no-jump-pointer -no-repeat -xsendevent -text "\[Alt_L]\[Right]""
  m:0x10 + b:9
I was getting repeated events, where a single click would back or forward up until it hit the end of history (very annoying) until I found a suggestion to add the -no-jump-pointer -no-repeat -xsendevent part to the configuration I had before. Now the buttons seem to work perfectly. I love the ability to navigate around websites just by clicking the buttons on my mouse. It's friendly to my wrists!

In conclusion, the Logitech MX 1000 is a fabulous mouse. It tracks remarkably well, feels good in my hand, and has buttons in the right places that really make a difference in my everyday computing experience. I've gotten so used to it that I had to buy a second mouse to use at home (I had been using the first only at work), because I just couldn't live without my tilt wheel and back and forward buttons. My only complaint about the hardware is that Logitech doesn't currently sell the Bluetooth version of the MX 1000 without a keyboard (in the MX 5000 bundle), which I don't use (although it makes my girlfriend happy to have a keyboard she can type on...I can't live without my Kinesis Advantage). With just a few steps, the mouse is easy to setup in Linux and X.org, and every feature of the mouse works perfectly. Kudos to the X.org developers who have made this configuration so much easier over the years!

Comments [1] | Trackbacks [0]

Fun With VLANs [Permalink]

Thu Jan 05 00:06:33 EST 2006
Category [Linux]

My friend and I were just playing around with a nifty little layer 3 switch and its VLAN configuration, trying to configure our two laptops (both running Linux) to be on 3 VLANs, alternately talking to each other on trunked ports and non-trunked ports. We got everything running, then decided that since my buddy didn't have his wireless interface up, I'd have to act as a router (so that he could get to my wireless router).

Fun facts:

ifconfig showed:

eth0      Link encap:Ethernet  HWaddr 00:03:93:57:5C:84
          inet addr:10.1.1.5  Bcast:10.255.255.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4886 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4502 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:547752 (534.9 KiB)  TX bytes:1566811 (1.4 MiB)
          Interrupt:41 Base address:0x8400

eth1      Link encap:Ethernet  HWaddr 00:30:65:15:4B:65
          inet addr:192.168.1.102  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2484 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3512 errors:5 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1964059 (1.8 MiB)  TX bytes:584380 (570.6 KiB)
          Interrupt:57

eth0.2    Link encap:Ethernet  HWaddr 00:03:93:57:5C:84
          inet addr:10.2.2.5  Bcast:10.255.255.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2612 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1968 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:279104 (272.5 KiB)  TX bytes:1317923 (1.2 MiB)

eth0.3    Link encap:Ethernet  HWaddr 00:03:93:57:5C:84
          inet addr:10.3.3.5  Bcast:10.255.255.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1682 errors:0 dropped:0 overruns:0 frame:0
          TX packets:976 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:153488 (149.8 KiB)  TX bytes:97704 (95.4 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:3869 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3869 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:365617 (357.0 KiB)  TX bytes:365617 (357.0 KiB)

I was able to use my laptop as a NATing router by running the following routing command:

sudo iptables -t nat -A POSTROUTING -s 10.2.2.10/24 -j SNAT --to-source 192.168.1.102

Our most fabulous setup was laptop A communicating to laptop B over VLAN 2, with laptop B trunked to VLANs 1-3, then laptop B performing NAT and forwarding packets over its other (wireless) interface) in order to get to my wireless access point, which performed NAT in order for us both to get to the larger Internet. Worked like a charm.

As a final test, we trunked both laptops to VLAN 2 and 3, configured laptop A with static host routes to the two IP addresses on laptop B, on VLAN 2 and 3 respectively, and tried to send a packet from the VLAN 2 interface on laptop A to the VLAN 3 interface on laptop A, with laptop B routing from VLAN 2 to VLAN 3. We didn't get that one to work, I think because the Linux kernel wasn't about to be fooled into thinking that it couldn't get to its own interface. We got some interesting packet traces, though.

23:57:28.392630 vlan 2, p 0, IP 10.2.2.10 > 10.3.3.10: ICMP echo request, id 33361, seq 13, length 64
23:57:28.392673 vlan 3, p 0, IP 10.2.2.10 > 10.3.3.10: ICMP echo request, id 33361, seq 13, length 64
23:57:29.393694 vlan 2, p 0, IP 10.2.2.10 > 10.3.3.10: ICMP echo request, id 33361, seq 14, length 64
23:57:29.393762 vlan 3, p 0, IP 10.2.2.10 > 10.3.3.10: ICMP echo request, id 33361, seq 14, length 64

Good times.

Comments [0] | Trackbacks [0]

One More Reason I Should Work For Google [Permalink]

Wed Jan 04 11:32:21 EST 2006
Category [General Miscellany]

What could be cooler than a giant mass of silly putty on your desk? Note the imprint of an entire newspaper.

Comments [0] | Trackbacks [0]

Spring Confusion [Permalink]

Thu Dec 29 14:27:21 EST 2005
Category [Java]

I spent about 6 hours yesterday trying to build a simple utility for my photo software that would replace an image in the database with an image from a file. I was using Spring to manage Hibernate sessions using a HibernateInterceptor to setup the transaction. I couldn't figure out why the session wasn't getting setup, and I was getting "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here" errors when running the program.

First, I added debugging statements to my code, which showed that when I was getting my bean from the ApplicationContext, my property setter was being called with a valid object, but the value of the field was null on the bean returned by the factory. I still haven't figured that one out. Anyway, eventually I turned up debug logging for the Spring classes and found that advice was being setup for my property accessors but not the method in which I was doing the work. Turns out I the method was private, and setting it to public solved the problem. I haven't found out yet whether or not it's possible to use an interceptor this way for a private method, but it's certainly not straightforward. Here's how my interceptor was setup originally:

  <bean id="hibernateInterceptor"
    class="org.springframework.orm.hibernate.HibernateInterceptor">
    <property name="sessionFactory">
      <ref local="sessionFactory"/>
    </property>
  </bean>

  <bean id="replaceImageManifestation"
    class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
      <bean
        class="com.trailmagic.image.util.ReplaceImageManifestation">
        <property name="sessionFactory">
          <ref local="sessionFactory"/>
        </property>
      </bean>
    </property>
    <property name="interceptorNames">
      <list>
        <value>hibernateInterceptor</value>
      </list>
    </property>
  </bean>

I ended up modifying the configuration to the following, which essentially does the same thing, but also declaratively manages transactions for me:

  <bean id="replaceImageManifestation"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager">
      <ref local="transactionManager"/>
    </property>
    <property name="target">
      <ref local="replaceImageManifestationTarget"/>
    </property>
    <property name="transactionAttributes">
      <props>
        <prop key="replace*">PROPAGATION_REQUIRED</prop>
      </props>
    </property>
  </bean>

  <bean id="replaceImageManifestationTarget"
    class="com.trailmagic.image.util.ReplaceImageManifestation">
    <property name="sessionFactory">
      <ref local="sessionFactory"/>
    </property>
    <property name="imageManifestationFactory">
      <ref local="imageManifestationFactory"/>
    </property>
  </bean>

Either configuration should work, and I still have beans using the former configuration. The problem was only in the method protection. Now it all works fine, and I know that next time I'll turn on the full debug logging sooner, although it can be hard to parse with all the extra output. Lessons learned:

  1. If something is behaving strangely, turn up debug logging before wasting time trying to figure out weird behavior.
  2. When playing around with spooky hidden code tricks like aspects, check your method protection!

Comments [0] | Trackbacks [0]

 

 

February 2012
Sun  Mon  Tue  Wed  Thu  Fri  Sat 
   1234
567891011
12131415161718
19202122232425
26272829   
       
<  Jan   Feb    Mar  >

Available categories: [/] [Entertainment] [Linux] [Meta] [General Miscellany] [Politics] [Technology] [Java]

Powered By blojsom   RSS Feed  RSS2 Feed  RDF Feed

html hits: 47884