Tuesday, October 28, 2008

Email problems with CXF

I was having a problem sending emails from my Apache CXF web service. The emails just wouldn't get sent from within an exception handler on the web service.

CXF (2.0.4 in my case) provides it's own mail classes (geronimo-javamail_1.4_spec-1.0-M1.jar and geronimo-activation_1.1_spec-1.0-M1.jar). The solution was to remove references to these libraries from the Classpath, and instead use the Sun libraries (mail.jar and activation.jar).

This led to my second problem. Now my CXF emails would send, but they were displaying "(no subject)" for the subject. A bit of digging revealed that the Geronimo mail jars were still floating around in my deployed webapp library folder. Completely purging the web app and redeploying it fixed this.

Wednesday, October 22, 2008

Viewing what you are about to dcommit

If you have stacked up a bunch of Git commits in the master, and you want to see what changes are going to be pushed to Subversion at the next git svn dcommit, you can use the commands below:

$git svn dcommit --dry-run (shows a list of commits that will be applied)
Committing to http://xyz/svn/Project/trunk ...
diff-tree bb2820965209ff83d016817b46268f289e65ab07~1 bb2820965209ff83d016817b46268f289e65ab07
diff-tree cff6b4575f6f7797652f030cbb8b425f57f4e08a~1 cff6b4575f6f7797652f030cbb8b425f57f4e08a

This reveals that there are two commits that are going to Subversion. You can then view the file names involved in each commit via:

$git diff-tree --stat bb2820965209ff83d016817b46268f289e65ab07~1 bb2820965209ff83d016817b46268f289e65ab07

Or you can view the actual source code changes in each commit, via:

$git diff-tree -p bb2820965209ff83d016817b46268f289e65ab07~1 bb2820965209ff83d016817b46268f289e65ab07

Tuesday, October 21, 2008

Ignoring local changes to tracked files in Git

If you have a file that lives in the Git repository, and you want to change it locally, but don't want to push it back to the repository, you can use the git update-index --assume-unchanged command.

In my case, I have a few properties files that hold machine-specific file paths. My production box is a Windows server, and my dev box is a Mac, so the paths can't be the same. But I like to have the production version of the file in the repository so I can check it out and build it straight into production.

Say the file is called build.properties. Once I've made a change to it, and run a git status, I can see it in my list of changes:

# On branch master
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# modified: build.properties

I could just not git add the file, but I like to use git add . and I keep forgetting. Using the Git ignore functionality won't work either. If I add the file name to my .gitignore file, it still shows up as modified.

# On branch master
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# modified: .gitignore
# modified: build.properties

The reason for this is that once a file is tracked in the repository, it won't be ignored. That would have worked if we never wanted the build.properties file in the repository in the first place though.

The solution is to stop Git from tracking changes to the file:
git update-index --assume-unchanged build.properties

Now when I do my git status:

# On branch master
nothing to commit (working directory clean)

Nice! And you can still explicitly add the file if you like. For more info, check the manual.

Edit: I'm not satisfied with this approach. When I do a "git add ." it actually adds my untracked files (even though they don't show up in the list of changes). This has given me a few surprises. I might have to also add the files to my .gitignore. Hmmmm. This is still a WIP!

Friday, October 17, 2008

How to "git svn dcommit" with uncommitted changes

If you committing directly off the master, and have some files modified locally that you do not want to push up to the SVN server, and you have not added them to the ignore list, then you will get a "file.abc: needs update" error message when you try to do your "git svn rebase". The way to get around this is to stash the local updates, rebase and dcommit, and then unstash them:

git svn rebase --> "file.abs: needs update"
git stash (save local changes away)
git stash list (have a look at what is stashed)
git svn rebase
git svn dcommit
git stash apply (back to where we were before)

Alternatively, use a branch for local changes and merge them into the master. This way the master only contains files that are going back to the SVN trunk.

Adding an empty folder to a Git repository

You can't actually add an empty folder to a Git repository - it handles files not folders. In my case though, I like to have the repo holding an empty copy of my "dist" folder so that I can grab the repo and then do a build without having to create the "dist" folder separately.

My solution is to created the folder and add a ".gitignore" file in there. In order to ignore everything in that folder (apart from itself), the .gitignore file has the following contents:

# Ignore everything in here apart from the .gitignore file

The only other thing I need to do is ensure that my ant build script does not delete the .gitignore file everytime I do a build and clean the "dist" folder. So I add this "exclude" code to my build.xml script:

<fileset dir="${dist.dir}">
<exclude name=".gitignore" />
<include name="**/*.*"/>

In hindsight, I probably should have gotten the build script to create the "dist" folder. Nevermind, but it was fun trying to find a solution!

Thursday, October 16, 2008

Find folder differences

To compare two folders on your Mac, and find the files that differ:
diff -rq dirA/ dirB/ |grep -v -e '\.svn' -e '\.git'|sort

Remove the '-q' option to see line differences:
diff -r dirA/ dirB/ > diff.txt

Friday, October 10, 2008

Error 51: Unable to communicate with VPN subsystem

If you're hitting "Error 51: Unable to communicate with VPN subsystem" when trying to start the VPN Client on your Mac, the solution is:

  • shutdown the VPN Client

  • start a terminal window

  • restart the VPN via:

  • sudo /System/Library/StartupItems/CiscoVPN/CiscoVPN restart

    Thanks to Anders for this one.