miracle occurs here|

Migrating Your WordPress Permalinks

August 26th, 2010 at 6:53 pm by Michael Scepaniak

When I first set-up my WordPress blog, I used the default permalink structure. For example:

http://milestoneinc.com/blogs/tech_blog/?p=79

I liked it because it kept the URL’s short. But, I came to understand the SEO benefits of readable URL’s. And the default structure made interpreting my Google Analytics reports a chore. So, I decided to change the structure to one that just used the name of the post:

/%postname%

And this works fine. You go into your Permalink Settings screen, specify the Custom Structure, save the .htaccess file, and the above URL changes:

http://milestoneinc.com/blogs/tech_blog/migrating-your-wordpress-permalinks

But, I could still access the old URL directly. This wasn’t cool to me, because the search engines would still drive visitors to the old link structure, Google Analytics would still show the obtuse links, and my URL’s would remain search-engine hostile. What I wanted to do was migrate the old URL’s to the new URL’s. It turns out that there are lots of WordPress plugins offering to do this for you. After much investigation and reading, the one I finally settled on was the Permalink Redirect WordPress Plugin by Scott Yang. Why? Primarily because of this thorough blog post about the Permalink Redirect Plugin by Michael Bubbo.

I followed the instructions and everything worked as expected. And when I look in my Apache access logs, I see the 301 redirect goodness that I expected:

12.345.678.999 - - [26/Aug/2010:02:37:58 -0500] "GET /blogs/tech_blog/?p=76 HTTP/1.1" 301 4224 "-"
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
12.345.678.999 - - [26/Aug/2010:02:37:58 -0500] "GET /blogs/tech_blog/migrating-your-wordpress-permalinks HTTP/1.1" 200 3798 "-"
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"

I hope this helps.

If you enjoyed this post, you might want to follow this blog!

A/Bingo Installation Tips

October 1st, 2009 at 5:48 pm by Michael Scepaniak

I wanted to incorporate A/B testing into a Rails project of mine. Being that I’m a fan of Patrick McKenzie and his micropreneurial pursuits, I decided to go with A/Bingo, his Ruby on Rails A/B testing framework. However, since I’m still pretty much a rookie when it comes to Ruby and Rails, I had some issues with the installation. Here are my tips…

In step #1, Patrick gives the installation options. I tried the script/plugin install command first, which seemed to execute fine. But I couldn’t figure out where the download got placed. So, I tried the git clone command, but, well, turns out I didn’t have git installed. (Remember, I is a rookie.) I quickly figured out that git can be easily installed (on OS X) using the Git OS X Installer. It worked great. I tried the git clone command again and an abingo directory got created in my local directory. Lovely.

In step #2, Patrick says to execute the ruby script/generate abingo_migration command. I tried, but I kept getting “Couldn't find 'abingo_migration' generator“. I figured that something was in the wrong place, but, me being a Rails novice, it took me a while to figure out. Do the following:

  1. Copy the contents of the abingo/lib directory to your Rails project’s lib directory.
  2. Copy the abingo/generators directory to your Rails project’s lib directory, too. (I figured this out by reading the usage/help for the script/generate command.

With regard to step #3, I must be using a different version of Rails (v2.3.3), because the names of the applicable files for me were application_controller.rb and application_helper.rb.

In the “Usage” -> “Statistical Significance” section, the command you want is experiment.describe_result_in_words, not experiment.describe_results_in_words.

Hope this helps anyone having similar issues.

If you enjoyed this post, you might want to follow this blog!

Maven – Install a POM-less JAR

January 11th, 2009 at 8:05 pm by Michael Scepaniak

At some point while using Maven, you’ll most likely come to a point where you need to install a POM-less artifact (probably a JAR) into your local Maven repository. This could happen for a number of reasons:

  • The JAR has never been published to a public Maven repository. This could be the case with a small, niche library.
  • You need to compile against JAR’s included in your runtime environment, which might be closed-source (e.g., WebSphere).
  • You might have some third-party JAR’s which you know work and are Maven-accessible, but you’re having difficulty determining their versions.

To install, run the following command (I think against any arbitrary pom.xml file):

mvn install:install-file -Dfile=[path/to/jar] -DgroupId=[group.id] \n
 -DartifactId=[package-id] -Dpackaging=jar -Dversion=[version] \n
 -DgeneratePom=true

So, for example, at one point in recent history, I needed to compile against some internal JBoss JAR’s. This is the command I used to install one of the JAR’s into my local Maven repository:

mvn install:install-file -Dfile=jboss-api-lib.jar \n
 -DgroupId=jboss.jboss-api -DartifactId=jboss-api-lib -Dpackaging=jar \n
 -Dversion=2.6.4 -DgeneratePom=true

If you enjoyed this post, you might want to follow this blog!

Confluence Install – Datasource “Access denied for user” Error

December 21st, 2008 at 7:50 pm by Michael Scepaniak

I was trying to install a Confluence instance in my hosting account. I had gone through the install and setup successfully locally on my Mac. But the setup on the host was failing:

I kept receiving some sort of access error:
Access denied for user 'foo_user'@'dz64.dailyrazor.com' (using password: YES)

I tried establishing the database connection manually through DbVisualizer, which worked fine:

jdbc:mysql://domain.com:3306/db_name?autoReconnect=true

I looked more closely at the error and realized that something was appending the username with the individual server my account was being hosted on (i.e., dz64.dailyrazor.com). I had a hard time figuring out who was at fault – Confluence, Tomcat, DBCP, or MySQL.

The source of the problem appeared to be my Tomcat resource definition:

Googling around didn’t provide me any answers. I tried replacing “domain.com” in the “url” attribute with “dz64.dailyrazor.com”, but this didn’t achieve anything. In the end, I figured out that specifying “localhost” was the answer:

url="jdbc:mysql://localhost:3306/db_name?autoReconnect=true"

This is what I was doing on my Mac, but it took me a while to figure out that the same had to be done on my host.

If you enjoyed this post, you might want to follow this blog!

Confluence Upgrade – Duplicate Entry Error

December 21st, 2008 at 7:22 pm by Michael Scepaniak

I’ve been running a Confluence installation (using a personal license) for a couple years. Recently, I’ve been experiencing some issues with it, and figured that it might be time to upgrade (from version 2.2.5, which is from July 2006, I’m guessing). At the time of this writing, the current version (and the version to which I wanted to upgrade), is version 2.10.

My upgrade process consisted of performing a clean install of version 2.10 and importing a backup of the content from my version 2.2.5 installation. According to the documentation, this is an expected and supported operation for these version numbers. But, it did not work. The error I received (in the atlassian-confluence.log file):

I did some Googling, but wasn’t able to find a solution. I looked closer at the information contained in the log and guessed that there were really only two records at issue, and that they both were drafts:

instance of 'class com.atlassian.confluence.pages.Draft' with id 13.

instance of 'class com.atlassian.confluence.pages.Draft' with id 14.

I opened the Confluence entities.xml file (located in the back-up zip) and searched for “draft”. As hoped, I found two elements:

I deleted these two elements from the XML file, re-zipped the back-up, re-executed the import, and it worked perfectly.

If you enjoyed this post, you might want to follow this blog!

Differences Between Hibernate and JPA

December 9th, 2008 at 8:02 pm by Michael Scepaniak

Fans of the Hibernate object-relational mapping (ORM) framework will realize that the Java Persistence API (JPA) is basically a standardization of that framework. And, if you’re like me, you really haven’t given much thought to JPA, because, gee, isn’t it just a watered-down Hibernate? Maybe, maybe not. (I’m not going to get into that here and now.)

It can be useful, though (even if only politically or procedurally), to code to JPA instead of the Hibernate API. If you find yourself in that situation, you may find this compare/contrast between the two API’s to be useful:

Hibernate JPA
SessionFactory EntityManagerFactory
Session EntityManager
sessionFactory.getCurrentSession().[method]() entityManager.[method]()
saveOrUpdate() persist()
Query.setInteger/String/Entity() Query.setParameter()
list() getResultList()
uniqueResult() getSingleResult()
uniqueResult() returns null getSingleResult() throws NoResultException
CriteriaQueries – yes CriteriaQueries – no

Additionally, there are a couple Hibernate-specific JPA-isms to keep in mind:

  • If the underlying JPA implementation is Hibernate, either/both annotations or/and mapping files may be used – at the same time. In such a situation, I believe the mapping files act as an override for the annotations.
  • The best of both worlds (in my mind) is to base the code (at an interface- or API-level) on JPA and its EntityManager, but to have the implementation interact with the Hibernate Session, which can be obtained by calling getDelegate() on the EntityManager.

If you enjoyed this post, you might want to follow this blog!

Change Apache DocumentRoot on Mac

November 22nd, 2008 at 3:14 pm by Michael Scepaniak

I was trying to configure Apache on my Mac to better incorporate it into my desktop development environment. Part of that included customizing the DocumentRoot location – changing it from the default directory (/Library/WebServer/Documents) and pointing (or linking) it to a directory that just made more sense to me. But it wasn’t as easy as I expected.

Trouble was, I couldn’t get Apache to reflect my changes to the Apache configuration file (httpd.conf), regardless of how many times I restarted Apache (via System Preferences). Finally I did a find (find /etc/ -name "httpd.conf") and figured out that I was editing the wrong configuration file (/etc/httpd/httpd.conf). My Mac was actually running Apache v2, but I was editing the configuration file for the now defunct (but apparently still present) Apache v1 installation. So I edited the correct configuration file (/etc/apache2/httpd.conf), restarted Apache as before, and everything worked as expected. :)

If you enjoyed this post, you might want to follow this blog!

mod_jk Fail, mod_proxy Success

November 14th, 2008 at 11:31 pm by Michael Scepaniak

I have a production site configured with Apache2 forwarding requests to Tomcat using mod_jk. I wanted to mimic this configuration on my desktop environment, but was not able to get it to work locally on my Mac. I ended up using mod_proxy locally instead. This is the ordeal I went through…

I grabbed a binary for Mac OSX (x86) from the Tomcat Connectors site, renamed it to mod_jk.so, and dropped it in the directory with the other modules. I made the necessary changes and additions to the Apache config files. Unfortunately, when I started Apache, I received the following error:

no suitable image found.  Did find: /usr/libexec/apache2/mod_jk.so:
mach-o, but wrong architecture

Googling the error helped me realize that I wasn’t alone with my issue and I figured out that I needed to build mod_jk from source, passing in some special flags to the build:

./configure CFLAGS='-arch x86_64' APXSLDFLAGS='-arch x86_64'
-with-apxs=/usr/sbin/apxs

This was great, but the next step (i.e., “make”), kept failing for me:

jk_global.h:66:21: error: apr_lib.h: No such file or directory
jk_global.h:67:25: error: apr_strings.h: No such file or directory
make[1]: *** [jk_ajp12_worker.lo] Error 1
make: *** [all-recursive] Error 1

I found lots of other pages explaining further variations of the same basic premise that I needed to build from source:

I followed all of these instructions, but still had no luck. Then I tried going down the DarwinPorts path:

But I didn’t get anywhere with this:

mike$ sudo port install mod_jk
...
Configuring APR library
Platform: i386-apple-darwin9.4.0
checking for working mkdir -p... yes
APR Version: 1.3.2
checking for chosen layout... apr
checking for gcc... /usr/bin/gcc-4.0
checking for C compiler default output file name...
configure: error: C compiler cannot create executables
See `config.log' for more details.

I came to suspect that I might require an install of Apple’s Xcode to get any of these solutions to work. So I started downloading it. As I was waiting for the download to complete, I started looking at mod_proxy as an alternative to mod_jk. Using mod_proxy wouldn’t accomplish my goal of mirroring the production configuration and I wasn’t sure if it could handle sticky sessions, but I didn’t need that at this point. So I gave it a whirl, fought with it a little bit, and eventually was able to configure a solution before I got anywhere with Xcode:

In Apache’s httpd.conf:

<Proxy balancer://myCluster>
   BalancerMember ajp://dev.milestoneinc.com:8010 route=node1
</Proxy>

ProxyPass /blogs !
ProxyPass /balancer-manager !
ProxyPass / balancer://myCluster/ stickysession=JSESSIONID

<Location /balancer-manager>
	SetHandler balancer-manager
</Location>

In Tomcat’s server.xml:

<Engine defaultHost="localhost" jvmRoute="node1" name="Catalina">

More information regarding mod_proxy and load-balancing/session-affinity:

If you enjoyed this post, you might want to follow this blog!

Here be Miracles

November 4th, 2008 at 7:29 pm by Michael Scepaniak

This blog is Milestone’s (meaning – Michael Scepaniak’s) attempt to give something back to the open-source software community. My evolution as a software developer started right about the same time the Web began to blossom, Java gained traction, and open-source software initiated its march toward ubiquity.

Without open-source software (specifically open-source software frameworks and components) such as the Spring Framework, Hibernate, Jakarta Commons, Tomcat, HtmlUnit, Freemarker, Linux, and others, I suspect that software development would be an immensely frustrating, passion-less chore. What open-source software brings to the table is creative, inspired, developer-focused solutions to real, trench-level problems and inefficiencies. It spurs openly-accessible, internet-wide discussion and peer-based support amongst a large community of geographically-isolated individuals.

I, like countless other software developers the world over, have benefited greatly from such software, both professionally and personally (not to mention monetarily). The effort required to build open-source software is significant, second only to the effort required to publish it, maintain it, test it, document it, and support it. The fact that the users of that open-source software (meaning, other software developers) tend to be a demanding, critical lot makes this effort even tougher.

I have massive amounts of respect for open-source software developers and everyone that contributes to fostering the ecosystem. With this blog, I hope to become a more meaningful participant of that ecosystem – more than simply a consumer.

I don’t expect to earn any oohs or aahs with this effort. It’ll simply be me sharing tips and tricks and know-how and workarounds that I have picked-up over my years doing software development. I don’t expect it to be the sort of blog to which people feel compelled to subscribe. Rather, I hope it becomes something that software developers stumble across when desperately googling for a solution to whatever gotcha’ they’ve found themselves caught in – a solution that I’ve already managed to figure out at some point in the past.

At the deepest, darkest point of maximum frustration, even a simple answer can seem like a miracle.

If you enjoyed this post, you might want to follow this blog!