- Setup your dial-up connection to use 'Internet Connection Sharing' (ICS) as described, for example here: http://support.microsoft.com/kb/306126
- Make sure that for Internet Connection Sharing 'Settings' you have enabled DNS to be provided by this new Internet host. Possibly DHCP, but not for now.
- Also make sure that the LAN network interface (on a laptop, that's usually 'Local Area Connection') now uses a static IP. Set it the way you would like your new internet gateway to appear on your home network. For example in my case, I already have a default gateway on192.168.0.1, so the new Internet-Host, should still use this primary gateway while it is not connected through the surf stick. The new internet host's ip is 192.168.0.100
Wednesday, December 23, 2009
Redundant home internet with a Surf Sticks and Internet Connection Sharing
Friday, October 30, 2009
MAC/IP lookup
Thursday, October 29, 2009
Automatic Restart Script for a Java service
... parse command line options ...
// register shutdown hook Runtime.getRuntime().addShutdownHook(new ShutdownHook(...));
// register uncaught exception handler
Thread.currentThread().setDefaultUncaughtExceptionHandler( new UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e)
{
e.printStackTrace();
if( e.getClass()==java.lang.OutOfMemoryError.class ) {
System.err.println("FATAL: shutting down because of java.lang.OutOfMemoryError ...");
System.exit(7);
}
}} );
File restart = new File("webservice.restart"); // tell the shell to restart me
restart.createNewFile();
... start your service ...
#!/bin/sh
#try to start service once
${JAVA_HOME}/bin/java -DREPLAYWEB ${JOPT} com.codestreet.replay.jms.shell.web.ReplayWeb $*
# restart again (until webservice.restart file was removed)
while [ -f webservice.restart ]; do
echo "### RESTART ###"
/bin/rm -f webservice.restart # let Java decide if we really want to restart
${JAVA_HOME}/bin/java -DREPLAYWEB ${JOPT} com.codestreet.replay.jms.shell.web.ReplayWeb $*
done
So Java decides if the service should be restarted and the shell actually performs the restart. - get the 'ps line' that contains the dummy JRE property (REPLAYWEB)
- get the task id of that process (awk is good enough)
- remove the temporary restart file so the start script won't restart automatically
- kill the process
psline=`/bin/ps -aef | /bin/grep "REPLAYWEB" | /bin/grep -v grep`
echo $psline
pid=`echo $psline | /bin/awk '{ print $2}'`
if [ $pid ]
then
/bin/rm -f webservice.restart
echo "stop_webservice: killing Web Service with pid=$pid"
kill $pid
else
echo "stop_webservice: Web Service was not running"
fi
Thursday, October 15, 2009
JAX-WS inside Jetty
Server jettyServer = new Server(port);
HandlerCollection handlerCollection = new HandlerCollection();
jettyServer.setHandler(handlerCollection);
/** 1) Publish WebService (JettyHttpServerProvider) */
String context = "/web/ws";
// 1.1) register THIS Jetty server with the JettyHttpServerProvider
new JettyHttpServerProvider().setServer(jettyServer);
// 1.2) make sure JAX-WS endpoint.publish will use our new service provider: JettyHttpServerProvider
System.setProperty("com.sun.net.httpserver.HttpServerProvider",
"org.mortbay.jetty.j2se6.JettyHttpServerProvider");
// 1.3) add an empty HandlerCollection to by setup by this provider
handlerCollection.addHandler( new HandlerCollection() );
// 1.4) use JAX-WS API to publish the endpoint (will use a JettyHttpServerProvider)
Endpoint endpoint = Endpoint.create(replayServiceImpl);
endpoint.publish("http://localhost:" + port + "/web/ws", replayServiceImpl);
/** 2) Publish WebGUI (Jetty) */
String context = "/gui";
// 2.1) configure File Resource Handler
ResourceHandler fileResourceHandler=new ResourceHandler();
fileResourceHandler.setWelcomeFiles(new String[]{"index.html"});
fileResourceHandler.setResourceBase(guiPath); // start here
// 2.2) configure 'gui' Context
ContextHandler guiHandler = new ContextHandler();
guiHandler.setContextPath(context);
guiHandler.setResourceBase(".");
guiHandler.setClassLoader(Thread.currentThread().getContextClassLoader());
guiHandler.setHandler(fileResourceHandler);
// 2.3) add this context handler
handlerCollection.addHandler(guiHandler);
/** 3) start JETTY server */
jettyServer.start();
jettyServer.join();
Embedding an HTTP daemon in Java
Publishing a JAX-WS Endpoint not just to localhost
HttpServer server = HttpServer.create(new InetSocketAddress(port), 3 ); // backlog
server.start();
endpoint.setExecutor( Executors.newFixedThreadPool(10) );
// publish WebService
HttpContext wsContext = server.createContext( "/" + service );
//wsContext.setAuthenticator(new TestBasicAuthenticator("test"));
endpoint.publish( wsContext );
Sunday, October 4, 2009
Quarkbase
Monday, September 7, 2009
60 seconds on SOAP-based Web Services
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
@WebService
// use RPC or 'wrapped' document-style
@SOAPBinding(style = Style.RPC)
//@SOAPBinding(style = Style.DOCUMENT,
// parameterStyle = SOAPBinding.ParameterStyle.WRAPPED )
public interface Example
{
@WebMethod public String getGreeting( @WebParam(name="myname") String myname);
}
And then implement the service itself. Use a thread-pool if your application is multi-threaded.
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
@WebService(endpointInterface = "simple.Example")
public class ExampleImpl implements Example
{
@Override
public String getGreeting(String myname)
{
return "hello, " + myname;
}
public static void main(String[] args)
{
String url = "http://127.0.0.1:9876/example";
System.out.println("Starting WebService at: " + url);
System.out.println("WSDL available at: " + url + "?wsdl");
Endpoint endpoint = Endpoint.create(new ExampleImpl());
//endpoint.setExecutor( Executors.newFixedThreadPool(10) );
endpoint.publish(url);
}
}
The resulting WSDL definition of this service can be looked at http://127.0.0.1:9876/example?wsdl (use Firefox or IE, not Chrome!). Any SOAP-based client (such as the XML Test Utility in General Interface, see previous post) can now invoke this service. Friday, September 4, 2009
General Interface Primer
- Look at the video tutorials, the best one for tables(matrix) isn't actually on that page, but here.
- Defining Javascript functions doesn't always work, even after Save/Reload. Try to restart and reload the page before giving up.
- You might sneeze at the package names, but trust me, in Javascript conflicts are easy to create. Here's a simple example on a function called jmsw.doAction(index) :
// name of the package to create: jmsw jsx3.lang.Package.definePackage( "jmsw", function(jmsw) { jmsw.doAction = function(index) // define doAction(index) { ... }; });
- Do Control+Click on a component (such as a button) to locate its definition in the 'Component Hierachy'.
- Float a Palette to get more space or to move it to the bottom panel: Upper Right Corner of a Palette View, click on 'Floating'. Use Menu->Palettes to enable/disable a palette.
- The 'XML Mapping Tool' always starts with the same default of ..Address.wsdl, but this will not be the one you will be working with. To change the default of this initial URI, edit C:\TIBCO\gi-3.8-max\GI_Builder\plugins\jsx3.ide.mapping\components\Inputs\wsdl.xml and search for 'Address, comment it out and add your own WebService URI:
<!-- use different default for XML Mapping Tool: <strings jsxname="jsx_schema_wsdlurl" jsxvalue="jsxplugin://jsx3.ide.mapping/samples/Address.wsdl" jsxwidth="100%"/> --> <strings jsxname="jsx_schema_wsdlurl" jsxvalue="http://127.0.0.1:9876/rs?wsdl" jsxwidth="100%"/>
Monday, August 31, 2009
Java Bi-directional Maps: Apache commons or Google collections ?
public class TestBidiMap
{
static BidiMap bimap = new DualHashBidiMap();
public static void main(String[] args)
{
bimap.put("D", 3);
System.out.println("D -> " + bimap.get("D") );
System.out.println("3 -> " + bimap.inverseBidiMap().get(3) );
}
}
Nice and easy, but unfortunately this version of BidiMap doesn't use Java generics, which I have learned to like over time (bimpap.get(3) will not show a compile error) !Google collections has an alternative that uses generics: BiMap
public class TestBiMap
{
static BiMap<String,Integer> bimap = HashBiMap.create();
public static void main(String[] args)
{
bimap.put("D", 3);
System.out.println("D -> " + bimap.get("D") );
System.out.println("3 -> " + bimap.inverse().get(3) );
}
}
Also nice and easy, what's interesting is the factory method HashBiMap.create(). This removes the need to duplicate the generics type specification of String, Integer. Kiss rules, so two points for Google collections here.
Summary: any mid-size Java project probably shouldn't live without Apache commons, but as a useful addition, Google collections is definitely worth a look.
Monday, August 17, 2009
Amazon S3 intro
Monday, August 10, 2009
Spring and Pipes&Filters
Finally an IoC container that almost everyone agrees on: Spring.
After many inhouse, half-baked attempts and 'framework wars' a default solution. TIBCO folks might remember the days of TAF (1996), GAF, XXTAF or PushBeans. Also
openadaptor.org should be noted here.
Now Spring certainly is nice and generic, but for building EAI adapters or 'message processing pipelines' it is not ideal. In case of these pipelines, the message path is very structured: from a source bean through several transformation beans until it finally reaches one (or many) sinks. XML already imposes an 'order of things' so an ideal configuration language of a little adapter might look something like this:
<pipelines>
<pipe name="Jdbc2JMSPipe">
<jdbc dbref="db1" querysql="select * from table1">
<concatenate method1="getFirstName" method2="getLastName" result="setName">
<jmsObject2MapMessage>
<jmsPublish topic="PERSON">
</pipe>
</pipelines>
This example configures a processing pipeline to get rows from a JDBC connection, invoke the concatenation filter, convert an object to a JMS MapMessage and finally publish the result to a JMS topic named 'T.PERSON'.
The configuration above is easy to understand and manipulate. One can imagine extensions with for-loops, if-clauses etc. For example:<pipelines>
<pipe name="Jdbc2JMSPipe">
<jdbc dbref="db1" querysql="select * from table1">
<concatenate method1="getFirstName" method2="getLastName" result="setName">
<jmsObject2MapMessage>
<if method="getName" startswith="a-z">
<jmsPublish topic="PERSON.LOWERCASE">
<else>
<jmsPublish topic="PERSON.UPPERCASE">
</else>
</if>
</pipe>
</pipelines>
Configuring the first example pipeline with Spring could look like this:
<beans>
<bean id="1" class="com.abc.jdbc" dbRef="db1" querySql="select * from table1">
<property name="next"> <ref bean="2"> </property>
</bean>
<bean id="2" class="com.abc.concatenate" method1="getFirstName" method2="getLastName" result="setName">
<property name="next"> <ref bean="3"> </property>
</bean>
<bean id="3" class="com.abc.jmsObject2MapMessage>
<property name="next"> <ref bean="4"> </property>
</bean>
<bean id="4" class="com.abc.jmsPublish" topic="T.PERSON"/>
</beans>
The order of beans is defined explicitly although XML already provides an order.<beans>
<bean id="1" class="com.abc.jdbc" dbRef="db1" querySql="select * from table1">
<property name="next"> <ref bean="following-sibling"> </property>
</bean>
<bean id="2" class="com.abc.concatenate" method1="getFirstName" method2="getLastName" result="setName">
<property name="next"> <ref bean="following-sibling"> </property>
</bean>
<bean id="3" class="com.abc.jmsObject2MapMessage>
<property name="next"> <ref bean="following-sibling"> </property>
</bean>
<bean id="4" class="com.abc.jmsPublish" topic="T.PERSON"/>
</beans>
Currently, I think XSLT would be the best solution since it keeps the clarity of the pipes&filters language.
Good books on EAI and Agile Programming
- Head First "Design Patterns" - 26 pages on the Decorator ? Finally the space it deserves ! If you found the "Consequences, Forces, Solutions, Implementation, Related Patterns"structure of other Patterns book too rigid. This one is for you. Finally an entertaining read on Patterns. "Patterns in Java" and even the GoFs books loose their glory after reading this one.
- "Client/Server Survival Guide" - Very old, but I liked the writing. (use Steven's "Unix Network Programming" as a reference)
- "Extreme Programming Explained" - there you go, little Agile programmer. Also some good tips on how to convince upper management of the benefits.
- "Java Extreme Programming Cookbook" - nice intro to a all the good technologies (as of 2005).
- "Java Message Service" (Monson-Haefel&Chappel) - no thrills, but all you really need. Writing concise books is a great virtue.
Ajax: Xpath-enabled Json queries
requestList( "class=TibjmsAdmin&method=getTopics&xpath=/*/*/name", "name", isAsync, topicList );2) Java Method call: On the Server-side, this request will execute the method TibjmsAdmin.getTopics() and create a Java object with some code similar to this:
if( className.equals("TibjmsAdmin") ) { // TODO: use ClassLoader (security?) Object invokee = jmsAdmin; } ... others ... // get specified method on specified class className = invokee.getClass().getName(); Class c = Class.forName(className); // className is TibjmsAdmin Method m = c.getMethod(method,argClasses); // method is getTopics, argClasses is null // invoke method and get return object returnObj = m.invoke(invokee, argObs);3) Java to XML: the next step is now to serialize this Java object to XML. I like to use XStream for this purpose because its extremly simple and straight-forward.
XStream xstream = new XStream(); String xml = xstream.toXML(returnObj);If the returned object does not produce the required results, you can do some magic by plugging in an XStream 'Converter' (not shown here). 4) Apply Xpath: Now that that we have the XML, we can apply the specified XPath to fiddle out the data that is really interesting for us. The following code will create a list of selected XML nodes.
NodeList nl = XmlUtils.selectNodeList(docBuilder,xmlString,xpath); StringBuffer sb = new StringBuffer("5) Return Json result: finally return the Json object back to the Browser using the Json tools."); for( int i=0;i<nl.getLength();i++ ) { Node node = nl.item(i); sb.append("<" + node.getNodeName() + ">" ); sb.append( node.getTextContent() ); sb.append("" ); } sb.append("\n
");
JSONObject json = XML.toJSONObject(xml); response.setContentType("text/plain"); if( out.equals("pretty") ) // pretty JSON response.getWriter().print( json.toString(2) ); else // or not response.getWriter().print( json.toString() );
Windows NT Service configuration
To debug current Windows Service configuration, try 'sc' on a command console.
For example 'sc query' pretty much shows the same configuration information as the registry tree which defines Windows services:
My Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
There's an interesting Windows Resource Kist that includes service configuration tools.
For example instsrv.exe to run ANY other .exe application as Windows service
Consistent Subversion icons in Windows and Eclipse
Debugging Visual C++ applications
Sometimes, the simplest trick is the best. I'm sure you all know this, but to debug a Windows application (for exampe a Windows NT Service), call 'DebugBreak'. In many situations this can be more handy than setting a breakpoint.
DebugBreak();
How to spawn a command shell under windows 'system' user
This trick can be useful if you want to debug user permission issues with a Windows NT service that logs on under "Local System account" (the default).
First, figure out your current system time:
C:\>time
The current time is: 6:15:18.57
Second, use the 'at' command to start an interactive command shell when the next minute starts:
C:\>at 6:16 /interactive cmd
Now inside this new command shell, try your command which is run under this new user.
Windows DLL load order
- The directories listed in the App Path registry key (if any)
- The directory where the executable module for the current process is located.
- The current directory.
- The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.
- The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.
- The directories listed in the PATH environment variable.
KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\test.exeAdd a sub-key named Path, set it's value to the full path of the DLL, for example:
Wednesday, July 22, 2009
How to display a non-scrolling background for a Java JScrollPane
public static void main(String[] args) {
JFrame frame = new JFrame("Overlay test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JScrollPane scroll = new JScrollPane();
scroll.getViewport().setBackground(Color.WHITE);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scroll.setPreferredSize( new Dimension(400,100));
frame.add(scroll);
final String text = "English";
final JTextArea ta = new JTextArea() {
{setOpaque(false);} // instance initializer
public void paintComponent (Graphics g) {
g.setFont(new Font("Verdana",Font.ITALIC,20));
g.setColor(Color.LIGHT_GRAY);
Rectangle rect = getVisibleRect();
int x = rect.width + rect.x - 14*text.length();
int y = rect.y + 20; // approx. height of the text
g.drawString(text, x, y);
super.paintComponent(g);
}
};
ta.setText("This text area contains an overlayed text that is BEHIND this text and does not scroll");
ta.setPreferredSize( new Dimension(600,100));
scroll.setViewportView(ta);
frame.pack();
frame.setVisible(true);
}
Friday, July 17, 2009
InstallShield Setup Prerequisites for PIA 2003, PIA 2007, VSOT, .NET2.0
- .NET Framework (2.0, for example, dotnetfx2.0.exe)
- Office 2007 Primary Interop Assemblies (o2007pia.msi)
- Visual Studio Tools for Office (vstor2005.exe)
- .NET Framework 2.0: "A File does or does not exist" [WindowsFolder]\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe --- Run setup if: Not Found
- PIA Office 2007: "A registry key does or does not exist" HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\Windows\CurrentVersion\Uninstall\{50120000-1105-0000-0000-0000000FF1CE} --- Run setup if: Not Found
- PIA Office 2003: "A registry key does or does not exist" HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\Windows\CurrentVersion\Uninstall\{91490409-6000-11D3-8CFE-0150048383C9} --- Run setup if: Not Found
- Visual Studio 2005 Office Tools: "A registry key does or does not exist" HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\Windows\CurrentVersion\Uninstall\{388E4B09-3E71-4649-8921-F44A3A2954A7} --- Run setup if: Not Found
10 Seconds on Windows Assemblies
Wednesday, July 15, 2009
InstallShield and Windows Services: ServiceExistsService doesn't work
// Indicates if the service with this key (e.g. myNewService) has been installedfunction BOOL windowsServiceExists(serviceKey) string szKey,szServiceName; number nRootKey; begin nRootKey = HKEY_LOCAL_MACHINE;
if (RegDBSetDefaultRoot (nRootKey) <> MessageBox ("Unable to set HKEY_LOCAL_MACHINE.", SEVERE); return FALSE; endif; szKey = "SYSTEM\\CurrentControlSet\\Services\\" + serviceKey; //MessageBox("Testing for service: " + serviceKey, INFORMATION); if (RegDBKeyExist (szKey) = 1 ) then //MessageBox("found service:" + szServiceName, INFORMATION); return TRUE; endif; return FALSE;end;
How to suppress InstallShield warning W7503
// dummy function to supress warning 'function defined but never called' prototype dummySuppressWarningW7503(); function dummySuppressWarningW7503()begin setRegistryValue("","",0,"");end;
// a little trick to stop the compiler from showing warnings if( FALSE ) then dummySuppressWarningW7503(); endif;