Wednesday 18 June 2014

JavaHg and ssh

I'm a fan of the JavaHg library.  It allows me to automate Mercurial commands in clean and elegant code.  But the documentation and help can be hard to find - you've basically got JavaDoc, the test cases and a  very small number of questions and answers on StackOverflow.

We had a problem talking to a remote Mercurial repository via ssh.  When doing this you're generally advised to put something like this in your home directory Mercurial.ini file:

[ui]
ssh = "C:\Program Files\TortoiseHg\TortoisePlink.exe" -ssh -i "C:\<path>\private_key.ppk" -C


[Note i've set up ssh access with keys to avoid entering a password each time.  Articles on how to do this are available on the web]

Although this worked for manual command line hg commands, it wouldn't work with the JavaHg code.  It turns out JavaHg is not picking up the home directory Mercurial.ini.  I'm not exactly sure why, but here is a code snippet of one solution that solves the issue:

RepositoryConfiguration repoConfig = new RepositoryConfiguration();
repoConfig.setSshBin("\"C:\\<path>\\TortoisePlink.exe\" -ssh -i \"C:\\<path>\\private_key.ppk\"");
File repositoryDirectory = new File("C:\\<path>\\<repo>");
Repository repo = Repository.open(repoConfig, repositoryDirectory);
PushCommand.on(repo).execute("ssh://<username>@<hostname>/<repo>");

I suspect there are other solutions, possibly setting ProcessBuilder's working directory, maybe updating the hgrc file in the repository with which you're working.  Over to you to experiment, hope I saved you a little time ;)

Update:  reading the source you find RepositoryConfiguration.setHgrcPath(null) will pick up the Mercurial.ini file as normal but note the default is to set hgrc path to "" which means Mercurial.ini is not picked up

Have a look here: http://grepcode.com/file/repo1.maven.org/maven2/com.aragost.javahg/javahg/0.4/com/aragost/javahg/RepositoryConfiguration.java

Saturday 1 March 2014

Zombie Windows Printers


Had a problem on Windows 7; a deleted printer kept reappearing after a reboot.

The problem was a document in it's print queue.  Here's how to deal with it:
  1. Stop the Printer Spooler service (type services.msc, select Printer Spooler and click stop)
  2. Delete all files in %SystemRoot%\SYSTEM32\SPOOL\PRINTERS
  3. Restart the Printer Spooler service

Wednesday 29 January 2014

Windows 7: Chrome displaying certain pages in italics (e.g. Google), Firefox displaying bold

I cannot figure the exact cause, but today my browsers started displaying web pages oddly - many Firefox pages were in bold font and many Chrome pages in italic font.

Turns out I'd somehow lost the Arial system font.  On Windows 7 take a look at Control Panel -> Appearance and Personalization -> Fonts.  In the Arial directory I had Arial Black, Bold, Italic, Narrow, etc... but no Arial Regular. I assume Firefox and Chrome were substituting the bold and italic fonts for the missing regular font.

Not certain this is the ideal solution, but it worked for me.  Run this update:
http://www.microsoft.com/en-gb/download/details.aspx?id=16083
Arial Regular was now back in Fonts directory and all was well after restarting the browsers.

Wednesday 22 January 2014

Spring ApplicationContext Bean Initialisation

Important Spring knowledge, but often poorly understood.  Beans are created and initialised by the ApplicationContext as follows (following sequence done for each bean):
  1. bean constructor called
  2. bean setters called
  3. postProcessBeforeInitialization() method called for each BeanPostProcessor
  4. bean @PostConstruct method(s) called
  5. if bean implements InitializingBean, afterPropertiesSet() method called
  6. bean init-method called if configured
  7. postProcessAfterInitialization() method called for each BeanPostProcessor
[ BeanFactoryPostProcessor is something different, it is called before any bean initialisation, and can used to alter the bean metadata]

Let's write some code to illustrate this:

TestBean.java

package com.example;

import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;

public class TestBean implements InitializingBean {

    private String text;

    public TestBean() {
        System.out.println("constructor");
    }

    public void setText(String text) {
        System.out.println("setter");
        this.text = text;
    }

    @PostConstruct
    public void postConstructInitialisation() throws Exception {
        System.out.println("postConstructInitialisation");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }

    public void init() {
        System.out.println("init");
    }

}


TestBeanPostProcessor.java

package com.example;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class TestBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("TestBeanPostProcessor postProcessBeforeInitialization");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("TestBeanPostProcessor postProcessAfterInitialization");
        return bean;
    }
}


application-context.xml (snippet)
    
    <bean class="com.example.TestBeanPostProcessor">

    <bean class="com.example.TestBean" init-method="init">
        <property name="text" value="Hello"/>
    </bean>


output:

constructor
setter
TestBeanPostProcessor postProcessBeforeInitialization
postConstructInitialisation
afterPropertiesSet
init
TestBeanPostProcessor postProcessAfterInitialization