iBlog Free Share
Tuesday, September 30, 2014
Hitleap Premium--->Shorte.st = $$$$$
1. Sign up to Hitleap , i suggest to purchase premium. (Earn some minutes)
2. Sign up to SHORTE.ST , make 3 shortened links and put them to hitleap. You can also Buy cheap traffic and make direct it to your shorte.st links.
3. MONEY MONEY MONEY!!! Minimum Payout: 10$
Paypal and Payoneer
Payment Proof:
non reflinks: www.shorte.st
www.hitleap.com
Wednesday, April 3, 2013
“Booting AMX” in GlassFish 3 with Groovy
In my previous blog post, I looked at using JMX as one of multiple methods supported by GlassFish 3 for its administration, monitoring, and management. In this blog post, I look in more detail at monitoring and managing GlassFish 3 via JMX and Groovy. I focus on local connection to GlassFish using the Attach API in this post, but I have covered remote JMX access of GlassFish in a previous post (see also Remote Glassfish V3.1 and the mystical JMX settings). The MBeans used for administration are generally the same in either case.
Because I’m using the Attach API in this post’s examples to connect to local Java processes that are started by me, I don’t need to specify the JMX remote connection propertiesjava.rmi.server.hostname,com.sun.management.jmxremote.port
, and com.sun.management.jmxremote.ssl=false
, and com.sun.management.jmxremote.authenticate
) for remote access. The easiest way to find Java processes meeting the standard of being on the local machine and being processes that I started is via use of jps (pre-JDK 7 and JDK 7) or jcmd (JDK 7 only), which I show in the next two screen snapshots.
As the above images indicate, GlassFish is running locally with PID (AKA Process ID or pid) 1584.To begin, I’m going to use Groovy to access the relevant MBeanServerConnection via the Attach API. This is done as shown in the following Groovy code (next two code listings) in which the method retrieveServerConnection(String)
accepts the PID and returns the MBeanServerConnection
for that Java process. That method uses another method in the code listing, retrieveUrlForPid(String, String)
, which uses the Attach API to provide a JMXServiceURL for the Java process.
retrieveServerConnection(String)
/** * Provide an MBeanServerConnection based on the provided process ID (pid). * * @param pid Process ID of Java process for which MBeanServerConnection is * desired. * @return MBeanServerConnection connecting to Java process identified by pid. */def MBeanServerConnection retrieveServerConnection(String pid){ def connectorAddressStr = "com.sun.management.jmxremote.localConnectorAddress" def jmxUrl = retrieveUrlForPid(pid, connectorAddressStr) def jmxConnector = JMXConnectorFactory.connect(jmxUrl) return jmxConnector.getMBeanServerConnection()}
retrieveUrlForPid(String, String)
/** * Provide JMX URL for attaching to the provided process ID (pid). * * @param @pid Process ID for which JMX URL is needed to connect. * @param @connectorAddressStr String for connecting. * @return JMX URL to communicating with Java process identified by pid. */def JMXServiceURL retrieveUrlForPid(String pid, String connectorAddressStr){ // Attach to the target application's virtual machine def vm = VirtualMachine.attach(pid) // Obtain Connector Address def connectorAddress = vm.getAgentProperties().getProperty(connectorAddressStr) // Load Agent if no connector address is available if (connectorAddress == null) { def agent = vm.getSystemProperties().getProperty("java.home") + File.separator + "lib" + File.separator + "management-agent.jar" vm.loadAgent(agent) // agent is started, get the connector address connectorAddress = vm.getAgentProperties().getProperty(connectorAddressStr) } return new JMXServiceURL(connectorAddress);}
With access to the MBeanServerConnection, I can start to do all types of useful things with Groovy and JMX to manage and monitor the a Java process. For example, the next code listing demonstrates how easy it is to now list the MBeans exposed by the Java process identified by a provided PID.
displayHostedMBeans(MBeanServerConnection)
/** * Display MBeans hosted on the provided MBeanServerConnection. * * @param mbeanServer MBeanServerConnection for which hosted MBeans are to be * provided. */def displayHostedMBeans(MBeanServerConnection mbeanServer){ mbeanServer.queryNames(null, null).each { println it }}
Running the above Groovy method against my running GlassFish instance with PID 1584 is demonstrated in the next screen snapshot.
displayHostedMBeansAttributesAndOperations(MBeanServerConnection)
/** * Display MBeans hosted on provided MBean Server along with the attributes and * operations available on each MBean. */def displayHostedMBeansAttributesAndOperations(MBeanServerConnection mbeanServer){ mbeanServer.queryNames(null, null).each { mbeanObjectName -> def mbeanInfo = mbeanServer.getMBeanInfo(mbeanObjectName) println mbeanObjectName println "\tAttributes:" mbeanInfo.attributes.each { attribute -> println "\t\t${attribute.type} ${attribute.name}" } println "\tOperations:" mbeanInfo.operations.each { operation -> def operationStr = new StringBuilder(); operationStr << "\t\t" << operation.name << "(" operation.signature.each { parameter -> operationStr << parameter.type << " " << parameter.name << ", " } def operationString = operationStr.contains(",") ? operationStr.substring(0, operationStr.length()-2) : operationStr println "${operationString})" } println "" }}
The previously displayed screen snapshot shows the bootAMX
operation available on the amx-support:type=boot-amx
MBean. This needs to be run to make other GlassFish-provided AMX MBean available. The next snippet of Groovy code, a method I’ve named bootAmx(MBeanServerConnection)
, invokes this bootAMX
operation to instruct GlassFish to expose significantly more details via its JMX interface.
bootAmx(MBeanServerConnection)
/** * "Boot AMX" on GlassFish. * * @param mbeanServer MBeanServerConnection to be used to invoke bootAMX * operation. */def bootAmx(MBeanServerConnection mbeanServer){ def amxObjectName = new ObjectName("amx-support:type=boot-amx") mbeanServer.invoke(amxObjectName, "bootAMX", null, null)}
When the simple Groovy just shown is run, GlassFish exposes significant more functionality via JMX. Now that I’ve “booted AMX,” I can rerun displayHostedMBeans(MBeanServerConnection)
to see the new MBeans that are available. A portion of this is shown next in the screen snapshot and the small-font text below it contains the entire output.
amx:pp=/domain/configs/config[server-config]/network-config,type=transportsamx:pp=/domain/configs/config[default-config]/iiop-service,type=iiop-listener,name=orb-listener-1amx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=property,name=encryption.key.aliasamx:pp=/domain/resources/jdbc-connection-pool[DerbyPool],type=property,name=serverNameamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[http-listener-1]/http,type=file-cacheamx:pp=/domain/configs/config[server-config],type=mdb-containeramx:pp=/domain/configs/config[default-config],type=system-property,name=HTTP_LISTENER_PORTamx:pp=/domain/configs/config[server-config]/web-container/session-config/session-manager,type=store-propertiesamx:pp=/ext,type=config-toolsamx:pp=/domain/nodes,type=node,name=localhost-domain1amx:pp=/domain/servers/server[server],type=application-ref,name=__adminguiamx:pp=/domain/configs/config[default-config]/network-config/protocols,type=protocol,name=sec-admin-listeneramx:pp=/J2EEDomain/J2EEServer[server]/WebModule[__admingui],type=Servlet,name=DownloadServlet,j2eeType=Servlet,J2EEServer=server,WebModule=__admingui,J2EEApplication=nullamx:pp=/domain/configs/config[server-config]/network-config/transports,type=transport,name=tcpamx:pp=/domain/configs/config[default-config],type=system-property,name=OSGI_SHELL_TELNET_PORTamx:pp=/domain/configs/config[server-config],type=thread-poolsamx:pp=/domain/configs/config[server-config]/security-service,type=audit-module,name=defaultamx:pp=/domain/secure-admin,type=secure-admin-principal,name="CN=localhost-instance,OU=GlassFish,O=Oracle Corporation,L=Santa Clara,ST=California,C=US"amx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ServerProvider],type=property,name=signature.key.aliasamx:pp=/,type=loggingjava.lang:type=MemoryPool,name=Code Cacheamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=property,name=encryption.key.aliasamx:pp=/domain/configs/config[default-config]/web-container,type=session-configamx:pp=/domain/configs/config[server-config]/security-service/auth-realm[file],type=property,name=fileamx:pp=/domain/configs/config[server-config]/iiop-service,type=iiop-listener,name=SSLamx:pp=/domain/configs/config[server-config]/security-service,type=message-security-config,name=SOAPamx:pp=/domain/configs/config[server-config]/iiop-service/iiop-listener[SSL_MUTUALAUTH],type=sslamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[http-listener-1],type=httpamx:pp=/domain/configs/config[default-config]/network-config,type=transportsamx:pp=/domain/configs/config[server-config]/http-service,type=virtual-server,name=serveramx:pp=/domain/configs/config[default-config]/web-container/session-config/session-manager,type=store-propertiesamx:pp=/domain/configs/config[default-config],type=ejb-containeramx:pp=/ext,type=system-statusamx:pp=/domain/configs/config[server-config]/network-config/protocols/protocol[admin-listener],type=httpamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=response-policyamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[HttpServlet]/provider-config[GFConsoleAuthModule],type=property,name=loginPageamx:pp=/domain/servers/server[server],type=resource-ref,name=jdbc/__TimerPooljava.lang:type=Memoryamx:pp=/mon/server-mon[server],type=compilation-system-mon,name=jvm/compilation-systemamx:pp=/domain/configs/config[server-config]/security-service,type=auth-realm,name=admin-realmamx:pp=/domain/configs/config[default-config]/log-service,type=module-log-levelsamx:pp=/mon/server-mon[server],type=server-runtime-monamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP],type=provider-config,name=XWS_ClientProvideramx:pp=/domain/configs/config[default-config]/web-container/session-config,type=session-manageramx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP],type=provider-config,name=XWS_ServerProvideramx:pp=/domain/configs/config[server-config]/thread-pools,type=thread-pool,name=http-thread-poolamx:pp=/domain/configs/config[default-config]/admin-service,type=property,name=adminConsoleDownloadLocationamx:pp=/domain/resources/jdbc-connection-pool[DerbyPool],type=property,name=connectionAttributesamx:pp=/domain/resources/jdbc-connection-pool[__TimerPool],type=property,name=connectionAttributesamx:pp=/domain/configs/config[default-config]/network-config/protocols,type=protocol,name=pu-protocolamx:pp=/domain/configs/config[server-config]/network-config,type=protocolsamx:pp=/ext,type=connector-runtime-api-provideramx:pp=/domain,type=resourcesjmxremote:type=jmx-connector-server,protocol=rmi_jrmp,name=systemamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[http-listener-2],type=sslamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[http-listener-2],type=httpamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=property,name=signature.key.aliasamx:pp=/,type=extamx:pp=/domain/configs/config[default-config]/monitoring-service,type=module-monitoring-levelsamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP],type=provider-config,name=ClientProvideramx:pp=/domain/configs/config[server-config]/security-service/message-security-config[HttpServlet]/provider-config[GFConsoleAuthModule],type=property,name=restAuthURLamx:pp=/domain/configs/config[server-config]/network-config/protocols/protocol[http-listener-1],type=httpamx:pp=/domain/configs/config[server-config]/jms-service,type=jms-host,name=default_JMS_hostamx:pp=/domain/configs/config[server-config]/web-container/session-config/session-manager,type=manager-propertiesamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ServerProvider],type=property,name=debugamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=property,name=debugamx:pp=/domain/configs/config[default-config]/network-config/network-listeners,type=network-listener,name=admin-listeneramx:pp=/domain/configs/config[default-config]/security-service/jacc-provider[default],type=property,name=repositoryamx:pp=/mon/server-mon[server],type=operating-system-mon,name=jvm/operating-systemamx:pp=/domain/configs/config[default-config]/security-service,type=audit-module,name=defaultjava.lang:type=MemoryPool,name=Survivor Spaceamx:pp=/domain/configs/config[default-config]/network-config,type=protocolsamx:pp=/domain/configs/config[server-config]/network-config/protocols/protocol[http-listener-2],type=sslamx:pp=/domain/configs/config[default-config]/thread-pools,type=thread-pool,name=http-thread-poolamx:pp=/J2EEDomain/J2EEServer[server]/WebModule[__admingui],type=Servlet,name=jsp,j2eeType=Servlet,J2EEServer=server,WebModule=__admingui,J2EEApplication=nullamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[pu-protocol],type=port-unificationamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=property,name=security.configamx:pp=/domain/configs/config[default-config],type=system-property,name=HTTP_SSL_LISTENER_PORTamx:pp=/domain/configs/config[default-config]/http-service,type=virtual-server,name=serveramx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=request-policyamx:pp=/domain/configs/config[server-config],type=iiop-serviceamx:pp=/domain/configs/config[default-config]/security-service,type=jacc-provider,name=defaultamx:pp=/domain/configs/config[default-config]/web-container/session-config/session-manager,type=manager-propertiesamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=request-policyamx:pp=/domain/configs/config[default-config]/security-service,type=auth-realm,name=certificatejava.nio:type=BufferPool,name=mappedjava.lang:type=Compilationamx:pp=/,type=runtimeamx:pp=/domain/configs/config[server-config]/monitoring-service,type=module-monitoring-levelsamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=property,name=dynamic.username.passwordamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=property,name=signature.key.aliasamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=property,name=encryption.key.aliasamx-support:type=amx-loader,name=configamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=property,name=dynamic.username.passwordamx:pp=/runtime,type=server-runtime,name=serveramx:pp=/domain/configs/config[server-config]/network-config/protocols,type=protocol,name=http-listener-1amx:pp=/domain,type=system-applicationsamx:pp=/domain/configs/config[server-config]/security-service,type=jacc-provider,name=defaultamx:pp=/J2EEDomain/J2EEServer[server]/JDBCResource[jdbc/__default]/JDBCDataSource[jdbc/__default],type=JDBCDriver,name=jdbc/__default,j2eeType=JDBCDriver,J2EEServer=server,JDBCResource=jdbc/__default,JDBCDataSource=jdbc/__defaultamx:pp=/domain/configs/config[server-config]/security-service/auth-realm[file],type=property,name=jaas-contextamx:pp=/domain/configs/config[server-config]/ejb-container,type=ejb-timer-serviceamx:pp=/domain/configs/config[default-config]/security-service,type=auth-realm,name=filejava.lang:type=Runtimeamx:pp=/J2EEDomain/J2EEServer[server]/WebModule[__admingui],type=Servlet,name=default,j2eeType=Servlet,J2EEServer=server,WebModule=__admingui,J2EEApplication=nullamx:pp=/domain/configs/config[default-config],type=web-containeramx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=property,name=debugamx:pp=/domain/system-applications/application[__admingui]/module[__admingui],type=engine,name=securityamx:pp=/domain/configs/config[server-config]/admin-service,type=jmx-connector,name=systemamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ServerProvider],type=response-policyamx:pp=/ext,type=realmsamx:pp=/,type=queryamx:pp=/domain/configs/config[default-config],type=thread-poolsamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[HttpServlet]/provider-config[GFConsoleAuthModule],type=property,name=loginErrorPageamx:pp=/domain/configs/config[server-config],type=connector-serviceamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=property,name=signature.key.aliasamx:pp=/domain/configs/config[default-config]/network-config,type=network-listenersamx:pp=/J2EEDomain/J2EEServer[server]/JDBCResource[jdbc/__TimerPool]/JDBCDataSource[jdbc/__TimerPool],type=JDBCDriver,name=jdbc/__TimerPool,j2eeType=JDBCDriver,J2EEServer=server,JDBCResource=jdbc/__TimerPool,JDBCDataSource=jdbc/__TimerPoolamx:pp=/domain/configs/config[default-config],type=system-property,name=JMS_PROVIDER_PORTamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ServerProvider],type=request-policyamx:pp=/domain/configs/config[default-config],type=availability-serviceamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[admin-http-redirect],type=http-redirectamx:pp=/,type=J2EEDomain,j2eeType=J2EEDomain,name=amxamx:pp=/domain/configs/config[default-config],type=system-property,name=IIOP_SSL_LISTENER_PORTamx:pp=/domain/configs/config[default-config]/iiop-service,type=iiop-listener,name=SSLamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=property,name=encryption.key.aliasamx:pp=/domain/configs/config[default-config]/network-config/transports,type=transport,name=tcpamx:pp=/domain/configs/config[default-config],type=system-property,name=JMX_SYSTEM_CONNECTOR_PORTamx:pp=/mon/server-mon[server],type=garbage-collector-mon,name=jvm/garbage-collectors/Copyamx:pp=/domain/configs/config[default-config]/http-service,type=virtual-server,name=__asadminamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=request-policyamx:pp=/,type=system-infoamx:pp=/domain/configs/config[default-config],type=group-management-serviceamx:pp=/domain/configs/config[default-config]/availability-service,type=web-container-availabilityamx:pp=/domain/configs/config[server-config]/group-management-service,type=failure-detectionamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=response-policyjava.lang:type=GarbageCollector,name=Copyamx:pp=/domain/configs/config[server-config],type=java-configamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP],type=provider-config,name=ServerProvideramx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[http-listener-2]/http,type=file-cacheamx:pp=/domain/configs/config[default-config],type=system-property,name=ASADMIN_LISTENER_PORTamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=request-policyamx:pp=/domain/configs/config[server-config]/network-config/protocols,type=protocol,name=http-listener-2amx:pp=/domain/configs/config[default-config]/jms-service,type=jms-host,name=default_JMS_hostamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=property,name=debugamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP],type=provider-config,name=ServerProvideramx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=property,name=signature.key.aliasamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=response-policyamx:pp=/domain/configs/config[server-config],type=web-containeramx:pp=/domain/configs/config[default-config]/security-service/auth-realm[admin-realm],type=property,name=jaas-contextjava.util.logging:type=Loggingamx:pp=/,type=toolsjava.lang:type=MemoryPool,name=Eden Spaceamx:pp=/domain/configs/config[default-config]/network-config/protocols,type=protocol,name=http-listener-2com.sun.management:type=HotSpotDiagnosticamx:pp=/domain/configs/config[default-config]/security-service,type=jacc-provider,name=simpleamx:pp=/domain/configs/config[default-config]/security-service,type=auth-realm,name=admin-realmamx:pp=/J2EEDomain/J2EEServer[server]/WebModule[__admingui],type=Servlet,name=FacesServlet,j2eeType=Servlet,J2EEServer=server,WebModule=__admingui,J2EEApplication=nullamx:pp=/domain/configs/config[server-config]/admin-service,type=property,name=adminConsoleContextRootamx:pp=/domain/configs/config[default-config],type=monitoring-serviceamx:pp=/domain/configs/config[server-config]/security-service,type=auth-realm,name=fileamx:pp=/domain/configs/config[server-config]/security-service/auth-realm[admin-realm],type=property,name=jaas-contextamx:pp=/domain/configs/config[server-config]/security-service/audit-module[default],type=property,name=auditOnamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=response-policyamx:pp=/domain/configs/config[default-config]/security-service/auth-realm[file],type=property,name=jaas-contextamx:pp=/domain/system-applications,type=application,name=__adminguiamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=property,name=security.configamx:pp=/domain/configs/config[default-config]/iiop-service/iiop-listener[SSL],type=sslamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=property,name=signature.key.aliasamx:pp=/domain/configs/config[default-config],type=connector-serviceamx:pp=/domain/configs/config[server-config],type=ejb-containeramx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=request-policyamx:pp=/mon/server-mon[server],type=garbage-collector-mon,name=jvm/garbage-collectors/MarkSweepCompactamx:pp=/domain/configs/config[default-config]/security-service/audit-module[default],type=property,name=auditOnamx:pp=/domain,type=secure-adminamx:pp=/domain/configs/config[default-config]/network-config/protocols,type=protocol,name=http-listener-1amx:pp=/,type=sampleamx:pp=/domain/configs/config[default-config]/group-management-service,type=failure-detectionamx:pp=/domain/configs/config[default-config]/network-config/network-listeners,type=network-listener,name=http-listener-1amx:pp=/domain/system-applications/application[__admingui],type=module,name=__adminguiamx:pp=/J2EEDomain/J2EEServer[server]/WebModule[__admingui],type=Servlet,name=ThemeServlet,j2eeType=Servlet,J2EEServer=server,WebModule=__admingui,J2EEApplication=nullamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ServerProvider],type=request-policyamx:pp=/domain/configs,type=config,name=default-configamx:pp=/domain/system-applications/application[__admingui]/module[__admingui],type=engine,name=webamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=property,name=dynamic.username.passwordamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=property,name=security.configjava.nio:type=BufferPool,name=directamx:pp=/domain/configs/config[server-config]/network-config/network-listeners,type=network-listener,name=http-listener-2amx:pp=/domain/configs/config[server-config]/iiop-service,type=orbamx:pp=/domain/configs/config[default-config],type=java-configamx:pp=/domain,type=property,name=administrative.domain.nameamx:pp=/domain,type=load-balancersamx:pp=/domain/resources/jdbc-connection-pool[__TimerPool],type=property,name=databaseNameamx:pp=/domain/resources,type=jdbc-connection-pool,name=DerbyPoolamx:pp=/domain/configs/config[default-config]/thread-pools,type=thread-pool,name=thread-pool-1amx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ServerProvider],type=property,name=encryption.key.aliasamx:pp=/domain/configs/config[default-config],type=diagnostic-serviceamx:pp=/domain/configs/config[default-config],type=security-serviceamx:pp=/domain/configs/config[default-config],type=system-property,name=IIOP_LISTENER_PORTamx:pp=/J2EEDomain/J2EEServer[server]/JDBCResource[jdbc/__TimerPool],type=JDBCDataSource,name=jdbc/__TimerPool,j2eeType=JDBCDataSource,J2EEServer=server,JDBCResource=jdbc/__TimerPoolamx:pp=/domain/resources/jdbc-connection-pool[DerbyPool],type=property,name=PortNumberamx:pp=/domain/configs/config[server-config],type=admin-serviceamx:pp=/domain/resources/jdbc-connection-pool[DerbyPool],type=property,name=DatabaseNameamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[admin-listener]/http,type=file-cacheamx:pp=/domain/configs/config[server-config]/web-container/session-config,type=session-managerjava.lang:type=MemoryPool,name=Tenured Genamx:pp=/domain/configs/config[server-config]/thread-pools,type=thread-pool,name=admin-thread-poolamx:pp=/domain/configs/config[server-config]/security-service,type=jacc-provider,name=simpleamx:pp=/domain/configs/config[server-config],type=monitoring-serviceamx:pp=/domain/configs/config[server-config]/security-service,type=property,name=default-digest-algorithmamx:pp=/domain/configs/config[default-config],type=network-configamx:pp=/,type=monamx:pp=/domain/configs/config[default-config],type=mdb-containeramx-support:type=boot-amxamx:pp=/domain/configs/config[default-config],type=transaction-serviceamx:pp=/J2EEDomain/J2EEServer[server],type=JDBCResource,name=jdbc/__default,j2eeType=JDBCResource,J2EEServer=serveramx:pp=/domain/configs/config[server-config]/network-config/protocols/protocol[admin-listener]/http,type=file-cacheamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[admin-listener],type=httpamx:pp=/domain,type=serversamx:pp=/domain/configs/config[default-config]/network-config/protocols,type=protocol,name=admin-http-redirectamx:pp=/domain/servers,type=server,name=serveramx:pp=/domain/configs/config[default-config]/availability-service,type=ejb-container-availabilityamx:pp=/domain/configs/config[server-config]/admin-service,type=property,name=ipsRootamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ServerProvider],type=response-policyamx:pp=/domain/configs/config[server-config]/iiop-service,type=iiop-listener,name=orb-listener-1java.lang:type=GarbageCollector,name=MarkSweepCompactamx:pp=/domain/configs/config[server-config]/admin-service,type=das-configamx:pp=/mon/server-mon[server],type=thread-system-mon,name=jvm/thread-systemamx:pp=/domain/resources,type=jdbc-resource,name=jdbc/__TimerPoolamx:pp=/J2EEDomain/J2EEServer[server]/JDBCResource[jdbc/__default],type=JDBCDataSource,name=jdbc/__default,j2eeType=JDBCDataSource,J2EEServer=server,JDBCResource=jdbc/__defaultamx:pp=/domain/configs/config[server-config]/security-service/jacc-provider[default],type=property,name=repositoryamx:pp=/domain/configs/config[server-config]/http-service,type=access-logjava.lang:type=ClassLoadingamx:pp=/domain/configs/config[server-config]/network-config/protocols,type=protocol,name=admin-listenerjava.lang:type=Threadingamx-support:type=amx-loader,name=j2eeamx:pp=/domain/configs/config[server-config]/security-service/auth-realm[admin-realm],type=property,name=fileamx:pp=/mon/server-mon[server],type=memory-mon,name=jvm/memoryamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=property,name=debugamx:pp=/domain/configs/config[default-config]/network-config/protocols,type=protocol,name=admin-listeneramx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=property,name=debugamx:pp=/domain/configs/config[server-config]/security-service,type=message-security-config,name=HttpServletamx:pp=/domain/configs/config[server-config]/web-container,type=session-configamx:pp=/domain/resources/jdbc-connection-pool[DerbyPool],type=property,name=Useramx:pp=/domain/configs/config[server-config]/thread-pools,type=thread-pool,name=thread-pool-1amx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=property,name=encryption.key.aliasamx:pp=/domain/configs/config[default-config]/http-service,type=access-logamx:pp=/mon,type=server-mon,name=serveramx:pp=/domain/servers/server[server],type=resource-ref,name=jdbc/__defaultamx:pp=/domain/configs/config[default-config],type=http-serviceamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=property,name=signature.key.aliasamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=property,name=dynamic.username.passwordamx:pp=/domain/resources/jdbc-connection-pool[DerbyPool],type=property,name=Passwordamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[pu-protocol]/port-unification,type=protocol-finder,name=admin-http-redirectamx:pp=/domain/configs/config[default-config]/security-service/auth-realm[file],type=property,name=fileamx:pp=/domain/configs/config[default-config]/security-service/auth-realm[admin-realm],type=property,name=fileamx:pp=/domain/configs/config[default-config]/iiop-service,type=orbamx:pp=/domain/configs/config[default-config]/admin-service,type=das-configamx:pp=/domain/configs,type=config,name=server-configamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[HttpServlet]/provider-config[GFConsoleAuthModule],type=request-policyamx:pp=/domain/configs/config[default-config],type=log-serviceamx:pp=/domain/configs/config[default-config]/iiop-service,type=iiop-listener,name=SSL_MUTUALAUTHamx:pp=/domain/configs/config[default-config],type=iiop-serviceamx:pp=/domain/configs/config[server-config]/iiop-service,type=iiop-listener,name=SSL_MUTUALAUTHamx:pp=/domain/configs/config[server-config]/security-service,type=auth-realm,name=certificateamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP],type=provider-config,name=ClientProvideramx:pp=/domain/configs/config[server-config],type=security-serviceamx:pp=/domain/configs/config[default-config]/security-service,type=message-security-config,name=SOAPamx:pp=/mon/server-mon[server],type=runtime-mon,name=jvm/runtimeamx:pp=/domain,type=lb-configsamx:pp=/J2EEDomain/J2EEServer[server],type=WebModule,name=__admingui,j2eeType=WebModule,J2EEServer=server,J2EEApplication=nulljava.lang:type=MemoryPool,name=Perm Genamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[HttpServlet],type=provider-config,name=GFConsoleAuthModuleamx:pp=/mon/server-mon[server],type=class-loading-system-mon,name=jvm/class-loading-systemjava.lang:type=MemoryManager,name=CodeCacheManageramx:pp=/domain/resources,type=jdbc-resource,name=jdbc/__defaultamx-support:type=mbean-trackeramx:pp=/domain/configs/config[server-config],type=network-configamx:pp=/domain/configs/config[server-config]/network-config/protocols/protocol[http-listener-2],type=httpamx:pp=/domain,type=configsamx:pp=/domain/configs/config[server-config]/http-service,type=virtual-server,name=__asadminamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP],type=provider-config,name=XWS_ClientProvideramx:pp=/domain/configs/config[default-config]/web-container/session-config,type=session-propertiesamx-support:type=amx-loader,name=startupamx:pp=/domain/configs/config[default-config],type=admin-serviceamx:pp=/domain/configs/config[default-config]/network-config/network-listeners,type=network-listener,name=http-listener-2amx:pp=/domain/configs/config[server-config],type=jms-serviceamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[sec-admin-listener]/http,type=file-cacheamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[sec-admin-listener],type=sslamx:pp=/domain,type=clustersamx:pp=/domain,type=nodesamx:pp=/domain/configs/config[default-config]/thread-pools,type=thread-pool,name=admin-thread-poolamx-support:type=AMXConfigLoaderamx:pp=/domain/configs/config[default-config]/ejb-container,type=ejb-timer-serviceamx:pp=/domain/configs/config[default-config]/iiop-service/iiop-listener[SSL_MUTUALAUTH],type=sslamx:pp=/domain/configs/config[server-config]/network-config/protocols/protocol[http-listener-2]/http,type=file-cacheamx:pp=/domain/resources,type=jdbc-connection-pool,name=__TimerPoolamx:pp=/domain/configs/config[default-config],type=jms-serviceamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=request-policyamx:pp=/domain/configs/config[server-config]/network-config/network-listeners,type=network-listener,name=admin-listeneramx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ServerProvider],type=property,name=debugamx:pp=/domain/configs/config[default-config],type=system-property,name=JAVA_DEBUGGER_PORTamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ServerProvider],type=property,name=encryption.key.aliasamx:pp=/domain/configs/config[server-config]/network-config,type=network-listenersamx:pp=/domain/secure-admin,type=secure-admin-principal,name="CN=localhost,OU=GlassFish,O=Oracle Corporation,L=Santa Clara,ST=California,C=US"amx:pp=/domain/configs/config[server-config]/network-config/network-listeners,type=network-listener,name=http-listener-1amx:pp=/domain/configs/config[server-config]/web-container/session-config,type=session-propertiesamx:pp=/,type=bulk-accessamx:pp=/domain/configs/config[server-config],type=group-management-serviceamx:pp=/domain/configs/config[default-config],type=management-rulesamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ServerProvider],type=property,name=signature.key.aliasamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[XWS_ClientProvider],type=response-policyamx:pp=/domain/configs/config[default-config]/availability-service,type=jms-availabilityamx:pp=/domain/configs/config[default-config]/admin-service,type=jmx-connector,name=systemamx:pp=/domain/configs/config[default-config]/http-service/virtual-server[server],type=property,name=default-web-xmlamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=response-policyamx:pp=/domain/configs/config[server-config]/network-config/protocols/protocol[http-listener-1]/http,type=file-cacheamx:pp=/domain/configs/config[server-config]/admin-service,type=property,name=adminConsoleDownloadLocationamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[sec-admin-listener],type=httpamx:pp=/domain/configs/config[server-config],type=transaction-servicejava.lang:type=OperatingSystemamx:pp=/J2EEDomain/J2EEServer[server],type=JVM,j2eeType=JVM,J2EEServer=serveramx:pp=/,type=pathnamesamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=property,name=security.configamx-support:type=amx-loader,name=extamx:pp=/domain/configs/config[server-config]/security-service/message-security-config[SOAP],type=provider-config,name=XWS_ServerProvideramx:pp=/domain/configs/config[server-config]/security-service/message-security-config[HttpServlet]/provider-config[GFConsoleAuthModule],type=response-policyamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ServerProvider],type=property,name=debugamx:pp=/domain/configs/config[default-config]/network-config/protocols/protocol[pu-protocol]/port-unification,type=protocol-finder,name=http-finderamx:pp=/J2EEDomain/J2EEServer[server],type=JDBCResource,name=jdbc/__TimerPool,j2eeType=JDBCResource,J2EEServer=serveramx:pp=/domain/configs/config[server-config],type=http-serviceamx:pp=/,type=domainamx:pp=/domain/configs/config[default-config]/security-service/message-security-config[SOAP]/provider-config[ClientProvider],type=property,name=encryption.key.aliasamx:pp=/domain,type=applicationsamx:pp=/domain/configs/config[default-config],type=system-property,name=IIOP_SSL_MUTUALAUTH_PORTamx:pp=/domain/configs/config[server-config]/iiop-service/iiop-listener[SSL],type=sslamx:pp=/J2EEDomain,type=J2EEServer,name=server,j2eeType=J2EEServeramx:pp=,type=domain-rootJMImplementation:type=MBeanServerDelegate
As this image and the small-font text demonstrate, “booting AMX” has led to GlassFish exposing significant monitoring and management capabilities via JMX.
Conclusion
This post has demonstrated using Groovy to explore the standard JMX MBeans provided by the Java Platform as well as the AMX beans that GlassFish provides. The last Groovy code snippet invokes GlassFish’s “bootAMX” operation to unleash significantly more GlassFish JMX-based monitoring and managing capabilities. Although all of this could be accomplished with a GUI-based JMX client such as JConsole or JVisualVM, there are advantages at times to running things in scripts. Using Groovy as demonstrated in this post allows scripts to easily interact with GlassFish for administration.
Reference: “Booting AMX” in GlassFish 3 with Groovy from our JCG partner Dustin Marx at the Inspired by Actual Events blog.
Source : feedproxy[dot]google[dot]com
Working with Amazon Web Services (EC2)
As posted before I attended to a technical handson AWS training last week. The subjects during these days were of course the standard EC2 and S3 services which I have used before. Added to that we worked with RDS, Elastic Load Balancing, SNS and VPC, Elastic Beanstalk and discussed a lot of terminology and business cases. In this post I setup a new EC2 server and connect to it with your MacOs although it will work similar in case of Linux. I have an account at AWS in place. Before you start make sure you have selected the correct region (for a simple demo it isn’t very big thing but when you are going to setup a real server it can make a big difference in the costs (network traffic) and latency although there are solutions for that). By the way, there are two approaches to setup your EC2 server, you can choose a “S3 backed” AMI (Amazon Machine Image) or a “EBS-bakced” AMI. There are a lot of good articles
available about the differences and when to use which one. In this demo I will install a “pre-baked” AMI with a complete WordPress setup installed. There are thousands of these AMI’s available in the AWS community. For this one launch the AWS Management Console at http://aws.amazon.com and choose the EC2 tab. In the AWS console make certain you selected the correct region and select ‘Images-AMIs’ in the left menu and search for “bitnami-wordpress”:
Select the AMI of your choice (I have 64-bit Ubuntu running WordPress 3.4.2.1) and click ‘Launch’. Now simply follow the steps of the wizard (although there is a lot to tell about almost every option in the wizard I simply go for the most default installation). At the Instance Details step make sure you select a Micro instance (to cut down the cost of having this demo running):
In the next two steps simply accept all defaults:
At the Create Key Pair step create a key pair if you haven’t already done so:
The next step Configure Firewall create a Security Group so we are able to access our Linux instance from the outside world by HTTP and SSH:
Finally review all your settings and if it is okay then launch the instance:
After a few seconds you should be able to see your new instance in the Instances overview in the AWS Management Console:
Please pay specific attention to the public DNS that is assigned to the instance. As you might be aware this DNS will change after you stopped and started this instance. So I use it now to show how to connect to the instance via SSH but you should not use this DNS as if it was a fixed IP/DNS. To work around this issue Amazon supplies Elastic IP which I show in another post.
To connect with SSH to this instance open up a Terminal on your Mac and type the following commands. First I had to narrow the permissions on the downloaded pem file for which I used: chmod u=r,go= 4synergy_palma.pem
Then I was able to connect to the Bitnami instance via SSH with: ssh -i 4synergy_palma.pem bitnami@ec2-54-246-78-211.eu-west-1.compute.amazonaws.com
as you can see here:
And of course we can enter our WordPress by opening the home URL in a web browser:
Reference: Working with Amazon Web Services (EC2) from our JCG partner Pascal Alma at the The Pragmatic Integrator blog.
Source : feedproxy[dot]google[dot]com
Evaluating new frameworks, libraries and technologies
Introduction
New frameworks and libraries are developed so fast it is nearly impossible to evaluate all of them. This can make it hard to judge whether a particular technology is worth investing (time) in. This post gives you some tips which may help when evaluating new technology.
Conceptual level
Although there are many different libraries and frameworks, most of them can be grouped based on some conceptual differentiation. The following concepts may help to
give an idea of this conceptual differentiation:
- Component based frameworks
- Request/response based frameworks
- Object Relational Mapping
- Map-reduce
- Key-value stores
- Messaging
- And many more…
When evaluating a specific technology it helps to identify to which concept or concepts it belongs. Before further analysis of a particular technology, make sure you understand the concepts. Without this understanding it is almost impossible to do an objective analysis. Understanding these concepts requires an investment in time. Usually in the form of reading, watching presentations, experimenting, training and talking to others. Understanding the concepts will make it easier to objectively evaluate a particular technology.
Simpler is usually better
One of the key actions in evaluating a particular technology is to determine if and how it satisfies the given requirements. A lot of frameworks and libraries provide a 1 minute introduction, a 5 minute guide, a 30 minute tutorial and more. I really like these sorts of introductions since it usually gets you up-to-speed quickly. Besides getting up-to-speed quickly, a more important factor is the complexity of the given solution. I really like the idea of ‘Make things as simple as possible, but not simpler’.
The starter guides, as mentioned above, present the readers with a relatively simple case or problem to demonstrate the key features of a given technology. To find out if a certain technology will fit I suggest to look at the complexity of the solution for the cases in the introduction guides.
In my opinion, if the solution for a relatively simple case or problem is complex and not easy to understand, how can a solution to a more complex problem be easy to understand? This complexity comes of course in various flavours:
- How much code do I need to write to get even the simplest things done?
- How many classes do I need to extend?
- What and how much configuration should I write?
- What is the quality of the documentation?
- How can I easily test my solution?
- Etc.
If the solution to a simple problem is indeed simple and easy to understand, it is worth investigating more time to find out if the technology satisfies your requirements. If the solution to a simple problem is not simple and not easy to understand, think long and hard before investing more time in it.
Conclusion
New frameworks and libraries are developed so fast it is nearly impossible to evaluate all of them. To speed up the decision process make sure you understand the technology at the conceptual level. Once you understand the conceptual level, experiment with the technology using introduction guides if they are available. If, from those introduction guides, solutions to a given problem are simple and easy to understand, it may be well worth spending more time investigating the particular technology for more complex problems. If not, proceed with care.
Reference: Evaluating new frameworks, libraries and technologies from our JCG partner Jamie Craane at the Jamie Craane’s Blog blog.
Source : feedproxy[dot]google[dot]com
Tuesday, April 2, 2013
Spring Integration – Apache Camel comparison
A year after v2.1 had been released, Spring Integration v2.2 is out with 3 new components MondoDB, Redis and JPA (even though the first 2 were listed also in v2.1 as message store, now they are available as Inbound and Outbound Channel Adapters), retry and other new features. As a comparison Apache Camel has also released v2.10 during the same period with around 18 new components. JPA support in Camel is available from long time, MongoDB since v2.10 and Redis since my commit couple of days ago. But of course the number of connectors (more than 130 for Camel) is not the most important characteristic for an integration framework (some might argue that). There are many other factors which matter when choosing an open source project for your needs. A quick search on the internet will show you which are the main questions you should ask before deciding which open source project to use
for your enterprise. Here are only couple of them and my biased answers:
1. What is the license? – Apache Camel (like all Apache projects) and Spring Integration both are using Apache License version 2.0 which is one of the most permissive licences. It basically says do whatever you want with the software.
2. Is the project actively developed? – According to ohloh.net for the last 12 months Apache Camel has 2415 commits from 24 committers whereas Spring Integration has 949 commits from 17 committers.
3. How mature is the project? – Both projects have started in 2007 and currently Spring Integration has 234K lines of code and is estimated to 60 years of effort, whereas Apache Camel has 800K lines of code and estimated to 220 years of effort.
4. How big and responsive is the community? – If you are creating a project different than ‘Hello World’, no matter how many books and tutorials there are, sooner or later you will have questions. And this is another area where Camel shines. According to Apache stats, Camel users and developers lists have around 700 subscribers combined who send 45 messages per day in total on average. If you ask a question, the chances are, you will get a response in a matter of minutes. On Spring Integration forums there are 24,355 messages since the start of the project, which on average means 13 messages a day.
5. How long it takes to fix a bug? – Personally for me this is a very important metric about open source projects. Imagine you found a bug in the project, a small bug that makes your day miserable. Then you go the extra mile to fix it, prove it with tests, submit a patch, describe it on the project forum/mailing list, but it never gets reviewed or included in the next release… Looking at the reported/resolved issues ratio for the last 30 days, as of mid January, Camel has resolved 80 out of 90 reported issues, whereas SI resolved 3 out of 19. But I strongly believe this is due to recent holiday season and the graph below will look better for SI later in the year.
6. How good is the documentation? – Both projects have quite extensive documentation, tutorials and plenty of blog posts. There are 3 books published covering Spring Integration – having read all of them, I can say more or less they talk about EIPs and repeat Spring Integration documentation but with better graphics. Camel for now has only one book published – Camel in Action by Claus Ibsen and Jonathan Anstey. There are aslo plenty of blog posts, tutorials and webinars for both projects out there. There is one thing that Spring Integration is missing though – CamelOne conference
7. Is there good tool support? – SpringSource develops Eclipse based Spring Tool Suite(STS) which has visual development tools for SI. IntelliJ IDEA also has SI support, but that is limitted to autocompliting varios endpoint options.
The most popular tool for developing Camel routes is Fuse IDE from FuseSource, which is also Eclipse based tool. There is also another Eclipse based graphical tool for Camel – Talend ESB
8. Can I get a commercial support if I need it? – If you have more money than time, both projects have companies offering commercial support. This is useful when you don’t have much time to spent for asking questions on the mailing lists or browsing the source code. There are also plenty of independent consultants you can reach through the mailing lists. These are only some of the questions you should ask yourself before adding one or the other dependency to your product. The more specific questions you should ask depends on your product portfolio, project stack, team abilities and motivation to learn new technologies.
Disclaimer: I’m Apache Camel committer and I absolutely adore Camel. I’ve also worked on projects where we chose Spring Integration over Apache Camel.
Reference: Spring Integration – Apache Camel comparison from our JCG partner Bilgin Ibryam at the OFBIZian blog.
Source : feedproxy[dot]google[dot]com
Telecommuting, Hoteling, and Managing Product Development
There are two sides of this conversation about telecommuting: the employee side and the management side. I hope you stick around for both sides. You can yell at me at the end.
Employees: You Owe the Company a Full Day of Work
I’ve been thinking since Marissa Meyer’s announcement what I would say about the end of telecommuting at Yahoo!. Best Buy employees now have to have a conversation with their managers about how they will manage their telecommuting.
People who work remotely full-time have an obligation to their team-mates to be
available, to make it easy for their team to find them. Once you have a telecommuter, you have a geographically distributed team, and anyone who’s been on one, knows the stresses that places on a team. It’s not impossible. It’s just harder on everyone.
I know the Bay Area has horrible traffic. I know the problems of being a parent and commuting to work. Mark and I managed those problems for more than 20 years, until our children graduated from high school. (Just because your children can drive does not mean you don’t worry about them. If they have mono in high school, you still worry about them. Yes, you do.)
And, I will tell you this: If you are camped out in the dining room or the living room on your computer and the kids are running around, or if you are driving the kids to their activities, you might be doing email, or you might be on the phone, but your work is not 100% on work. You are not focused. You cannot possibly be giving 100% of your brain to work. Some part of your brain is wondering what the kids are doing. Or, wondering why the kids got so quiet. Or, wondering why you can’t hear the dog anymore. This is not a full day of work.
If you work from home on a regular basis, and you regularly work from the dining room, I’ll say the truth: you are shortchanging the company. You are not delivering a full day of work.
Staying home when a child has a fever? Of course, you must. Staying home when a child has the mumps or measles or chickenpox? (Does anyone get these diseases now?) You must. You and your spouse can discuss/fight over who has to take time off. We did. You can, too. Good luck. That’s a marriage/career issue. I’m not getting into the middle of that one.
But the cost to the team of you not working with the team on a daily basis? That is so high. If you want to know, measure the value stream in your project.
Anyone can make telecommuting work. Especially if it’s just one or two days a week. But five days a week? No. That’s not reasonable for your teams. And, I wonder why you chose that. I bet some of you chose that because your company did not provide a reasonable environment for you.
Telecommute in an emergency? Of course. On a regular basis? Especially if you want agile teams? Craziness.
Once you have established teams, teams can create their own norms. But it takes many iterations and lots of trust to build those established norms.
Companies, You Owe Employes a Reasonable Work Environment
Once we get past the emergency days when parents must take time off from work, and have people back at work, what will we do with these people? We need reasonable work environments. Here’s what constitutes reasonable for me:
- A team room for an agile team
- Rooms for cross-functional teams to meet. (Even if you are not agile, you need rooms for cross-functional teams to meet. Yes, you do.)
- An “office” for each person. It can be small if there is a team room.
- Sufficient meeting space, so you do not have to go to buildings half a mile away for a meeting. Companies: Measure the time wasted trying to find a meeting room!
- Enough bathrooms, so people like me don’t have to go to the men’s room, and shout “Woman incoming, there is no woman’s room on this floor.” (Don’t think I’m kidding. I’m not.)
- Enough parking, close enough so people don’t have to wonder how long it will take them drive home, after they’ve hiked to their car
- Lighted parking lots. Keep it safe, please.
There is more. That is the minimum. Think coffee, water, that kind of thing.
You know what’s missing from that list? The stupid “hotel” idea that companies thought they could get away with. “We don’t need a place for employees. They’ll plug in wherever they are, and that will be their place for the day.” The hoteling idea is total nonsense.
Well, that’s a way to make people feel as if they are welcomed, and part of a team. Not! This blog is called “Managing Product Development” for a reason. If you want to release products, you need teams. If you want teams of people to organize in some way, they need to know where to congregate. How the heck can they know where to congregate, if they have no place to sit?
“Hoteling” employees has to be just about the most stupid idea I ever heard. I don’t know who dreamed it up. Probably some architect who has a lovely office to sit in. Or an executive who has a permanent desk.
People need to know they are wanted. Do you want your employees? Give each of them a permanent space.
Oh, and don’t talk to me about introverts. Highly introverted people, who prefer to not talk to people, want to know where they will sit. They just don’t want to talk to more than one person while they sit there. Okay, some of them don’t even want to talk to one person, but they want a place to sit.
What Do You Need for Your Product Development?
Can you make telecommuting work for your organization? Of course you can. You can make geographically distributed teams work. I have a workshop on it, and I just published a paper on it. You are a smart person, working with smart people. The question is this: What will make your product development proceed faster, with more ease, with less cost, and allow you the most flexibility?
One of the reasons I urge my clients to transition to agile if they can, is that agile can provide them those benefits. However, agile is not for everyone. If they decide agile is not for them, we discuss if an iterative approach is best, or an incremental approach is best, or a combination is best. It’s all about what they need for their product development.
If you don’t need a geographically distributed organization, don’t create one. Telecommuting creates one. Instead, make it a policy that everyone come to work. Phase the policy in, as Meyer is. Have a conversation, as Best Buy is.
And, if you got sucked into those crazy workplace architectures, make enough offices/cubicles of large enough size, so that people have a place to put their stuff and work. Oh, and make the cube walls shorter, so people can see me coming, so I don’t have to wear a bike flag. That’s just craziness, too.
Talk With Your People
This is not about anti-parents. This is about bringing working people together for innovation and creativity. How do you solve the problem of long commutes, a reasonable workspace, and core hours?
The best thing you can do is talk about this issue with the people in your company. If you are a manager, don’t think you have all the answers. You might not even understand all the problems.
You don’t have to agree with me. I’m sure I will set off the mommy-wars and the daddy-wars, and the manager-wars, and the employee-wars. Well, I have on my flame-retardant suit. Go ahead. I’m ready! If you have the discussion in your organization about what is best for you, I have done a good job.
Reference: Telecommuting, Hoteling, and Managing Product Development from our JCG partner Johanna Rothman at the Managing Product Development blog.
Source : feedproxy[dot]google[dot]com
Monday, April 1, 2013
FitNesse your ScalaTest with custom Scala DSL
This article won’t be about FitNesse. As matter of fact I don’t like this tool very much and it seems to be loosing momentum, judging by the traffic on an official mailing list. Instead we will implement trivial internal DSL on top of Scala to simplify testing code, inspired by DoFixture
. DoFixture
in FitNesse allows one to write very readable acceptance tests almost in plain English using Wiki pages:
!|CarRegistrationFixtureTest| !1 Registering car!2 Registering brand new car for the first time | register | brand new car | by | any owner | in | any country |
What might not be obvious is that the last line is actually executable and calls good old Java (or Scala for that matter) method:
class CarRegistrationFixtureTest extends DoFixture { val carService = new CarService def registerByIn(car: Car, owner: Owner, where: Country) = { //... } }
Notice how oddly named registerByIn
method maps to “ register brand new car by any owner in any country” wiki syntax. What we will learn today is writing very simple, custom Scala DSL that is even more readable and does not require new tool and testing framework.
The same test written in ScalaTest would look something like this:
class CarRegistrationSpec extends FeatureSpec with GivenWhenThen { val carService = new CarService() feature("Registering car") { scenario("Registering brand new car for the first time") { Given("Owner and brand new car") //... When("Car registered") carService.registerCar(brandNewCar, anyOwner, anyCountry) //... } }}
Nothing fancy, ordinary registerCar()
method call. The rest of the test (as well as the declaration of brandNewCar
, anyOwner
and anyCountry
) is not relevant to our discussion. We can make it a little bit more readable by explicitly naming parameters:
carService.registerCar(car = brandNewCar, owner = anyOwner, where = anyCountry)
However it’s not clear whether this is actually more readable for e.g. non-programmers. But since we already use descriptive FeatureSpec
, can we make Scala code a little bit more human eye-friendly? Of course! Our biggest friends are infix notation and fluent API pattern:
def register(car: Car) = new { def by(owner: Owner) = new { def in(country: Country) = carService.registerCar(car, owner, country) }}
Looks weird, but put this code in your test and enjoy much more fluent call:
register(brandNewCar).by(anyOwner).in(anyCountry)
This is as far as Java can go, but Scala has infix method call syntax, which is equivalent and looks beautiful:
register(brandNewCar) by anyOwner in anyCountry
Why couldn’t we skip first parentheses? It is a limitation on where infix notation can be used (only one-argument method calls on an object). Fortunately we can easily refactor our internal testing DSL by pushing noun (owner) onto first place and using implicit conversion:
implicit def fluentCarRegister(owner: Owner) = new { def registers(car: Car) = new { def in(country: Country) = carService.registerCar(car, owner, country) }}
…which can be used as follows:
anyOwner registers brandNewCar in anyCountry
If you got lost, the line of code above is still Scala and is still executable. If you don’t quite get what’s happening, here is a desugared syntax:
fluentCarRegister(anyOwner).registers(brandNewCar).in(anyCountry)
Tests are all about readability and maintainability. Many people are scared of DSLs because often they are hard to implement and debug. As I showed in this short article, writing really simple yet impressive test DSL in Scala is both simple and rewarding. Moreover there is no reflection or magic meta-programming.
Reference: FitNesse your ScalaTest with custom Scala DSL from our JCG partner Tomasz Nurkiewicz at the NoBlogDefFound blog.
Source : feedproxy[dot]google[dot]com