Thursday, November 6, 2008

How to switch on log4net internal logging

If you want log4net to show its own internal logging, which is useful to find out where it is looking for your XML configuration file, you can add the following XML to your app.config file:

<configuration>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
</configuration>

Note that if you are using log4net in a DLL, this goes into the app.config file for the EXE that is calling your DLL.

Monday, November 3, 2008

Log4Net using a named config file

Setting up Log4Net with your configuration in the app.config file is pretty straight-forward to do - a quick Google will lead to a number of posts on how to do this.

But if you decide to move your log4net config settings to an external file (convention seems to be "log4net.config") then there are a few misconceptions floating around. There are only two further steps you need to take to achieve this:

1. Copy the <log4net> ... </log4net> section out of your app.config and save it into a new file called log4net.config. You should totally remove it from the app.config file once you feel confident - it is no longer needed.

2. Modify your AssembyInfo.cs file by removing this:

[assembly: log4net.Config.XmlConfigurator
(Watch = true)]


and replacing it with this:

[assembly: log4net.Config.XmlConfigurator
(ConfigFile = "log4net.config", Watch = true)]


Now if you fire up the IDE and run it, your logging should still work. If you don't see any logging, then check that the log4net.config is in the current application path - if you are running from the IDE then that will be where the EXE lives at "../MyProject/bin/Debug/". If you've placed the log4net.config file in your project home folder then you can get it working through the IDE with this:

[assembly: log4net.Config.XmlConfigurator
(ConfigFile = "../../log4net.config", Watch = true)]


Note that this will need to be reviewed come deployment time!

OR, even better, just select the config file in the IDE and, in the Properties window, change the "Copy to Output Directory" value to "Copy always". Now when you build it through the IDE it will follow your compiled file around. Nice!

Note that you do NOT need to add log4net.Config.XmlConfigurator.Configure() or log4net.Config.XmlConfigurator.Configure({file name}) to the code in your project! This does a manual configuration which overrides what is in the AssemblyInfo.cs file. If you get the AssemblyInfo.cs parameters right then that is all you need.


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
*
!.gitignore


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:


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


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!