Author: psmith Date: Thu Mar 6 22:07:58 2008 New Revision: 634548 URL: http://svn.apache.org/viewvc?rev=634548&view=rev Log: Now that log4j 1.2.16 has the new createSocket method, we can trap this, store the details of the port/address, and use that in the broadcast of what the SocketHubAppender is listening on.
Includes test case. Changed dependency on zeroconf to require log4j 1.2.16-SNAPSHOT until release. Modified: logging/log4j/companions/zeroconf/trunk/pom.xml logging/log4j/companions/zeroconf/trunk/src/main/java/org/apache/log4j/net/ZeroConfSocketHubAppender.java logging/log4j/companions/zeroconf/trunk/src/main/java/org/apache/log4j/net/Zeroconf4log4j.java logging/log4j/companions/zeroconf/trunk/src/test/java/org/apache/log4j/net/ZeroConfSocketHubAppenderTest.java Modified: logging/log4j/companions/zeroconf/trunk/pom.xml URL: http://svn.apache.org/viewvc/logging/log4j/companions/zeroconf/trunk/pom.xml?rev=634548&r1=634547&r2=634548&view=diff ============================================================================== --- logging/log4j/companions/zeroconf/trunk/pom.xml (original) +++ logging/log4j/companions/zeroconf/trunk/pom.xml Thu Mar 6 22:07:58 2008 @@ -163,6 +163,7 @@ </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> + <configuration> <descriptors> <descriptor>src/assembly/bin.xml</descriptor> @@ -171,6 +172,7 @@ </configuration> <executions> <execution> + <phase>package</phase> <goals> <goal>assembly</goal> </goals> @@ -181,6 +183,7 @@ <artifactId>maven-javadoc-plugin</artifactId> <executions> <execution> + <phase>package</phase> <goals> <goal>jar</goal> <goal>javadoc</goal> @@ -210,7 +213,7 @@ <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> - <version>1.2.9</version> + <version>1.2.16-SNAPSHOT</version> </dependency> <dependency> <groupId>jmdns</groupId> Modified: logging/log4j/companions/zeroconf/trunk/src/main/java/org/apache/log4j/net/ZeroConfSocketHubAppender.java URL: http://svn.apache.org/viewvc/logging/log4j/companions/zeroconf/trunk/src/main/java/org/apache/log4j/net/ZeroConfSocketHubAppender.java?rev=634548&r1=634547&r2=634548&view=diff ============================================================================== --- logging/log4j/companions/zeroconf/trunk/src/main/java/org/apache/log4j/net/ZeroConfSocketHubAppender.java (original) +++ logging/log4j/companions/zeroconf/trunk/src/main/java/org/apache/log4j/net/ZeroConfSocketHubAppender.java Thu Mar 6 22:07:58 2008 @@ -18,60 +18,74 @@ import java.io.IOException; import java.lang.reflect.Method; +import java.net.InetAddress; +import java.net.ServerSocket; import javax.jmdns.JmDNS; import javax.jmdns.ServiceInfo; import org.apache.log4j.Level; - /** * A sub-class of SocketHubAppender that broadcasts its configuration via Zeroconf. * * This allows Zeroconf aware applications such as Chainsaw to be able to detect them, and automatically configure * themselves to be able to connect to them. * + * This class relies on log4j 1.2.16 or later. + * * @author psmith * */ public class ZeroConfSocketHubAppender extends SocketHubAppender { - public static final String DEFAULT_ZEROCONF_ZONE="_log4j._tcp.local."; + public static final String DEFAULT_ZEROCONF_ZONE = "_log4j._tcp.local."; private String zeroConfZone = DEFAULT_ZEROCONF_ZONE; - + private Object logger; private Method logInfoMethod; private Method logErrorMethod; - + + private int actualPortUsed; + private InetAddress actualAddressUsed; + public ZeroConfSocketHubAppender() { setName("SocketHubAppender"); try { - Method getLoggerMethod = this.getClass().getMethod("getLogger", new Class[0]); + Method getLoggerMethod = this.getClass().getMethod("getLogger", + new Class[0]); logger = getLoggerMethod.invoke(this, new Object[0]); - logInfoMethod = logger.getClass().getMethod("info", new Class[] {Object.class}); - logErrorMethod = logger.getClass().getMethod("error", new Class[] {Object.class}); - }catch(Exception e) { + logInfoMethod = logger.getClass().getMethod("info", + new Class[] { Object.class }); + logErrorMethod = logger.getClass().getMethod("error", + new Class[] { Object.class }); + } catch (Exception e) { // we're not in log4j1.3 land } } + public void activateOptions() { super.activateOptions(); - try { JmDNS jmDNS = Zeroconf4log4j.getInstance(); ServiceInfo info = buildServiceInfo(); - logWithlog4j12Compatibility(Level.INFO,"Registering this SocketHubAppender as :" + info); + logWithlog4j12Compatibility(Level.INFO, + "Registering this SocketHubAppender as :" + info); jmDNS.registerService(info); } catch (IOException e) { - logWithlog4j12Compatibility(Level.ERROR,"Failed to instantiate JmDNS to broadcast via ZeroConf, will now operate in simple SocketHubAppender mode"); + logWithlog4j12Compatibility( + Level.ERROR, + "Failed to instantiate JmDNS to broadcast via ZeroConf, will now operate in simple SocketHubAppender mode"); } } + private ServiceInfo buildServiceInfo() { - return new ServiceInfo(zeroConfZone, getName(), getPort(), "SocketHubAppender on port " + getPort() ); + return new ServiceInfo(zeroConfZone, getName(), actualPortUsed, + "SocketHubAppender on port " + this.actualPortUsed); } - + private void logWithlog4j12Compatibility(Level level, String message) { - if(logger!=null && logInfoMethod!=null & logErrorMethod!=null) { + if (logger != null && logInfoMethod != null & logErrorMethod != null) { try { switch (level.toInt()) { case Level.INFO_INT: @@ -96,7 +110,6 @@ return zeroConfZone; } - /** * Sets the ZeroConf zone to register this device under, BE CAREFUL with this value * as ZeroConf has some weird naming conventions, it should start with an "_" and end in a ".", @@ -108,20 +121,39 @@ * @param zeroConfZone */ public void setZeroConfZone(String zeroConfZone) { -// TODO work out a sane checking mechanism that verifies the value is a correct ZeroConf zone + // TODO work out a sane checking mechanism that verifies the value is a correct ZeroConf zone this.zeroConfZone = zeroConfZone; } + public synchronized void close() { super.close(); try { JmDNS jmDNS = Zeroconf4log4j.getInstance(); ServiceInfo info = buildServiceInfo(); - logWithlog4j12Compatibility(Level.INFO,"Deregistering this SocketHubAppender (" + info + ")"); + logWithlog4j12Compatibility(Level.INFO, + "Deregistering this SocketHubAppender (" + info + ")"); jmDNS.unregisterService(info); } catch (Exception e) { - logWithlog4j12Compatibility(Level.ERROR,"Failed to instantiate JmDNS to broadcast via ZeroConf, will now operate in simple SocketHubAppender mode"); + logWithlog4j12Compatibility( + Level.ERROR, + "Failed to instantiate JmDNS to broadcast via ZeroConf, will now operate in simple SocketHubAppender mode"); } } - - + + protected ServerSocket createServerSocket(int socketPort) + throws IOException { + ServerSocket serverSocket = super.createServerSocket(socketPort); + this.actualPortUsed = serverSocket.getLocalPort(); + this.actualAddressUsed = serverSocket.getInetAddress(); + return serverSocket; + } + + public final int getActualPortUsed() { + return actualPortUsed; + } + + public final InetAddress getActualAddressUsed() { + return actualAddressUsed; + } + } Modified: logging/log4j/companions/zeroconf/trunk/src/main/java/org/apache/log4j/net/Zeroconf4log4j.java URL: http://svn.apache.org/viewvc/logging/log4j/companions/zeroconf/trunk/src/main/java/org/apache/log4j/net/Zeroconf4log4j.java?rev=634548&r1=634547&r2=634548&view=diff ============================================================================== --- logging/log4j/companions/zeroconf/trunk/src/main/java/org/apache/log4j/net/Zeroconf4log4j.java (original) +++ logging/log4j/companions/zeroconf/trunk/src/main/java/org/apache/log4j/net/Zeroconf4log4j.java Thu Mar 6 22:07:58 2008 @@ -32,43 +32,39 @@ */ public class Zeroconf4log4j { - private static final JmDNS instance; - - static { - try { - instance = new JmDNS(); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("Failed to initialize JmDNS"); - } - } + private static JmDNS instance; /** * Returns the current instance of the JmDNS being used by log4j. * - * @throws IllegalStateException if JmDNS was not correctly initialized. + * @throws RuntimeException if JmDNS was not correctly initialized. * * @return */ - public static JmDNS getInstance() { - checkState(); - return instance; - } - - private static void checkState() { + public static synchronized JmDNS getInstance() { if (instance == null) { - throw new IllegalStateException( - "JmDNS did not initialize correctly"); + try { + instance = new JmDNS(); + } catch (Exception e) { + throw new RuntimeException( + "Failed to create an instance of JmDNS", e); + } } + return instance; } - + /** - * Ensures JmDNS cleanly broadcasts 'goodbye' and closes any sockets, and (more imporantly) + * Ensures JmDNS cleanly broadcasts 'goodbye' and closes any sockets, and (more importantly) * ensures some Threads exit so your JVM can exit. + * + * This clears an internal [EMAIL PROTECTED] JmDNS} variable so that a subsequent call to [EMAIL PROTECTED] #getInstance()} + * will initialize and create a new one. * */ public static void shutdown() { - checkState(); - instance.close(); + if (instance != null) { + instance.close(); + instance = null; + } } } Modified: logging/log4j/companions/zeroconf/trunk/src/test/java/org/apache/log4j/net/ZeroConfSocketHubAppenderTest.java URL: http://svn.apache.org/viewvc/logging/log4j/companions/zeroconf/trunk/src/test/java/org/apache/log4j/net/ZeroConfSocketHubAppenderTest.java?rev=634548&r1=634547&r2=634548&view=diff ============================================================================== --- logging/log4j/companions/zeroconf/trunk/src/test/java/org/apache/log4j/net/ZeroConfSocketHubAppenderTest.java (original) +++ logging/log4j/companions/zeroconf/trunk/src/test/java/org/apache/log4j/net/ZeroConfSocketHubAppenderTest.java Thu Mar 6 22:07:58 2008 @@ -2,6 +2,7 @@ import javax.jmdns.JmDNS; import javax.jmdns.ServiceEvent; +import javax.jmdns.ServiceInfo; import javax.jmdns.ServiceListener; import junit.framework.TestCase; @@ -10,59 +11,100 @@ * Some test methods to validate that the ZeroConf stuff works as expected/advertised * * @author psmith - * */ public class ZeroConfSocketHubAppenderTest extends TestCase { + private final class TestServiceListener implements ServiceListener { + final ModifiableBoolean addedFlag = new ModifiableBoolean(); + final ModifiableBoolean removedFlag = new ModifiableBoolean(); + private ServiceInfo lastInfo; + private ServiceEvent lastEvent; + + public void serviceAdded(ServiceEvent event) { + addedFlag.setValue(true); + lastEvent = event; + } + + public void serviceRemoved(ServiceEvent event) { + removedFlag.setValue(true); + lastEvent = event; + } + + public void serviceResolved(ServiceEvent event) { + lastInfo = event.getInfo(); + } + } + private static final int DEFAULT_TIMEOUT_FOR_ZEROCONF_EVENTS_TO_APPEAR = 2000; + JmDNS jmdns; + + protected void setUp() throws Exception { + super.setUp(); + jmdns = Zeroconf4log4j.getInstance(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + Zeroconf4log4j.shutdown(); + + } + /** - * This does a simple test, as a test harness, to make sure the Appender can be created - * and that it can shutdown appropriately. in older versions of JmDNS a non-daemon thread - * could hold the JVM open preventing it from shutting down. - * - * @see com.strangeberry.jmdns.tools.Main for a ZeroConf Network browser in Swing allowing you to see the broadcasts + * This does a simple test, as a test harness, to make sure the Appender can be created and that + * it can shutdown appropriately. in older versions of JmDNS a non-daemon thread could hold the + * JVM open preventing it from shutting down. * + * @see com.strangeberry.jmdns.tools.Main for a ZeroConf Network browser in Swing allowing you + * to see the broadcasts * @throws Exception */ public void testSimpleTest() throws Exception { - JmDNS jmdns = Zeroconf4log4j.getInstance(); - - final ModifiableBoolean addedFlag = new ModifiableBoolean(); - final ModifiableBoolean removedFlag = new ModifiableBoolean(); - - /** - * This is just a test to make sure I'm not stupid. - */ - assertTrue(!addedFlag.isSet()); - assertTrue(!removedFlag.isSet()); - - jmdns.addServiceListener(ZeroConfSocketHubAppender.DEFAULT_ZEROCONF_ZONE, new ServiceListener() { - public void serviceAdded(ServiceEvent event) { - addedFlag.setValue(true); - - } - - public void serviceRemoved(ServiceEvent event) { - removedFlag.setValue(true); - } - - public void serviceResolved(ServiceEvent event) { - - }}); + TestServiceListener testServiceListener = new TestServiceListener(); + jmdns.addServiceListener( + ZeroConfSocketHubAppender.DEFAULT_ZEROCONF_ZONE, + testServiceListener); ZeroConfSocketHubAppender appender = new ZeroConfSocketHubAppender(); appender.setName("SimpleTest"); appender.activateOptions(); - + Thread.sleep(DEFAULT_TIMEOUT_FOR_ZEROCONF_EVENTS_TO_APPEAR); - - assertTrue("Should have detected the addition", addedFlag.isSet()); - + + assertTrue("Should have detected the addition", + testServiceListener.addedFlag.isSet()); + appender.close(); - Zeroconf4log4j.shutdown(); - + Thread.sleep(DEFAULT_TIMEOUT_FOR_ZEROCONF_EVENTS_TO_APPEAR); + + } + + public void testRandomPortWorksOk() throws Exception { + + TestServiceListener testServiceListener = new TestServiceListener(); + jmdns.addServiceListener( + ZeroConfSocketHubAppender.DEFAULT_ZEROCONF_ZONE, + testServiceListener); + + + ZeroConfSocketHubAppender appender = new ZeroConfSocketHubAppender(); + appender.setPort(0); + appender.setName("RandomPortTest"); + appender.activateOptions(); + assertTrue("Port should have been automatically chosen", appender + .getActualPortUsed() != 0); + assertTrue("Should have detected the addition", + testServiceListener.addedFlag.isSet()); + + ServiceEvent lastEvent = testServiceListener.lastEvent; + jmdns.requestServiceInfo(lastEvent.getType(), lastEvent.getName()); + assertEquals( + "The JmDNS port ServiceInfo should have matched what we expect to broadcast from the appender", + testServiceListener.lastInfo.getPort(), appender + .getActualPortUsed()); + appender.close(); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]