zaterdag 20 november 2010

Devoxx 2010

I know for sure I was there. Can't remember a lot though... Will check my notes and get back to this post soon.

maandag 13 september 2010

Modify servo for continuous rotation

I struggled a lot modifying the tiny servo's for continuous rotation. I tried several methods.

The first one, replacing the pot meter with resistors did work for some time on a first servo. You have remove the nob of the gears that prevent it from turning around and force the pot meter to turn over all the way. Then disconnect the wires from the pot meter and put some resistors in between that match the pot meter's value. But my soldering skills aren't that great so it came lose very quickly and I burned the second one I wanted to modify. You have to get these soldering and new resistors into the very limited space of these micro servo's. 

Since the internals are so limited I looked for another way to get this done. I found on the web you can in fact glue the pot meter in the center (has to be in te center!! power on servo to center) and then you only need to drill out the hole on the gear for the shaft of the pot meter so that it can turn freely. Removing the nob on the gears for free rotation is still needed. But this way you don't need to soldering anything. The pot meter is than functioning as a simple resistor since it's never moving anymore. It's always indicating it's in the center position, like you simulated with the resistors in the previous method.

The last option is to buy them modified :).

Android cellbot TRRStan received and built

You can order this kit from http://www.cellbots.com/. It's a very basic kit and therefor very affordable. It contains all elements (except for the android phone that is :)) to built a robot powered by 2 AA batteries and moving on 2 smaller wheels and 2 cd's. It's controlled by an Android Phone connected with only the headphone connector. You can get a very basic application that lets you control the connected servo's from the screen.



I just needed the logic board and the modified servo's for my own creation so I ordered. Once received (order well handled, did need to pay taxes over it since package claimed it's actual value) I immediately started building. I had some troubling finding written instructions next to the youtube movie referenced in the packaged documentation. Once found (check cellbots menu on the right) I started soldering. I had some practice by now :). 

The written instructions stated all TRRS connector (that is the sound plug on your phone) parts should be on a different circuit. My board had the mic and the com (ground) ports shorten. I asked this on the cellbots google group and quickly got an answer (like usual, great support from developers themselves). This is normal, check the google group for more information on this. It worked nonetheless.

This is my board soldered and with 2 servo's connected. It's not completely according to instructions. I should have taken the notted cable from the TRRS connector through the hole near where it's soldered. My mistake but it's not in my way so I won't take the time to desolder. If you were building according to spec it would be in your way. The hole I used is ment to attach the battery holder to the board. So do it correct if you're building as is. Also the ground (black) wire of the BAT- connector should be on the other side of the board. I quickly fixed it since cable broke and this way I didn't have to desolder. Yes I don't like desoldering :). The board is not that hard to solder, you've got plenty of space. 



This is the construction I came up with. I posted about those wheels before. I got them from a technics set. You need part 32019 (the tires) and part 86652 (the wheels). You can attach a servo rod with ty raps. The construction is hold together with metal parts from a cheap meccano like set. Not sure if you can still buy original meccano?




The phone is mounted on the metal bracket in front using the velcro strap. It doesn't really have a front wheel. Instead I used some rubber to just sweep over the floor. Therefor it's not yet offroad enabled :).

Next step is to work out some remote software. I can control it form the device already with this simple Servo Tester apk from the cellbots repository. I'll be working on a bluetooth application based on the bluetooth chat sample from the android api. Simply communicating commands like forward/backwards/turn left/turn right in order to control it form another android bluetooth device. I'll post the apk when I have something running.

donderdag 29 juli 2010

Teach Yourself Programming in Ten Years

Check this link: Teach Yourself Programming in Ten Years by Peter Norvig and find out why experience is so important! I'm halfway there :D.

ear deployment on glassfish 3 (vs glassfish 2)

I recently had some trouble deploying an ear file to the new glassfish v3. It works on glassfish v2. After some investigation I found that the way the ejb's were located in the ear file was not accepted by version 3 of the glassfish application server.

In short the jar files on the top level of the ear package are no longer visible by default. You need to put libraries, available to all modules of the package into the default lib folder. Or you'll have to add their location to the manifest file (Class-Path)

With maven you can set the class-path to a manifest file with the defaultLibBundleDir tag and you can put modules/dependencies in other locations with the manifestEntries tag. An example:


<build>
 <plugins>
  <plugin>
   <artifactId>maven-ear-plugin</artifactId>
   <version>2.4.2</version>
   <configuration>
    <!-- required since glassfish v3 -->
    <defaultLibBundleDir>lib</defaultLibBundleDir>
    <archive>
     <manifestEntries>
      <Class-Path>YOUR_VALUES_HERE</Class-Path>
     </manifestEntries>
    </archive>

You can read about this in detail at the following link: http://docs.sun.com/app/docs/doc/821-1759/ggpnv?l=en&a=view

Stricter JAR Visibility Rules


Java EE 6 imposes stricter JAR visibility rules than did Java EE 5.
As a result, some older applications might fail.

The Java
EE 6 specification
imposes strict rules about which JAR files are
visible from an enterprise archive (EAR) file. Refer to section EE.8.3.3;
specifically, application client modules should not have access to any EJB
JAR file unless the application client JAR file's manifest Class-Path refers to the EJB JAR file(s) explicitly.

This is a change from GlassFish Server v2, in which application clients
automatically had access to all EJB JAR files in the EAR file and all JAR
files at the top level of the EAR file. To comply with the stricter specification
language, GlassFish Server 3.0.1 cannot automatically provide application
clients with access to these JAR files.

This new, stricter behavior imposed by Java EE 6 can be addressed as
follows:


  • If the application is deployed to a GlassFish Server v2 domain,
    Upgrade Tool will preserve the GlassFish Server v2 behavior for that application
    in that domain. For more information about upgrading, see Oracle GlassFish Server 3.0.1 Upgrade Guide.
  • Change the manifest Class-Path of the client
    so it refers explicitly to the JAR files on which it depends. The Class-Path must not list JAR files in the EAR file's library directory. As
    required by the specification, all JAR files in that directory are available
    to all modules in the EAR file. This directory is /lib by
    default, or can be set to some other directory using library-directory in
    the application.xml descriptor.
  • Deploy the EAR file using the optional --property
    compatibility=v2
    setting. This preserves the GlassFish Server v2 behavior
    for that application when it is deployed to GlassFish Server 3.0.1.

This change in behavior is also discussed in Chapter 1, GlassFish Server Compatibility Issues, in Oracle GlassFish Server 3.0.1 Upgrade Guide.

Blogger has beautiful new layouts!

You noticed the new layout of my blog? All done with standard blogger templates. You can choose a template and then set color scheme and background image. I believe this is a great upgrade for the older templates that were getting so outdated.

Cheap(er) Dell look alike keyboard from Trust

I always liked the Dell keyboards as pictured below.



But they are a way too expensive (if you can even find one brand new). This keyboard from dell comes close but is costing me 50 EUR! Second hand is no option (jaaiks)!

Trust has some wireless keyboard (and mouse) that looks very similar to this Dell. It's ment for both left as right handed people (symmetrical) and comes close to the design of the dell keyboards I like. You can get it for half the price of a Dell!



The feedback of the keys is quit hard, like an older keyboard. Exactly what I like. I got a Belgium layout (azerty) version. Not sure if it's available in US qwerty layout for transformation to dvorak keyboard layout.

dinsdag 27 juli 2010

Tethering on Macbook Pro with HTC Hero Android Device

Yes you can go for a paid app like PDANet to install on your android device and to link with a client on your mac.

Why not use a free opensource alternative? Azilink tethering for Android is your free solution. Installation is pretty straight forward as long as you don't skip any steps. For me it didn't work out of the box until I found a script that did the trick. I now have to connect, start the client on my android and execute the script and I'm connected.

This is the tutorial that worked for me. I used tunnelblick as an openvpn client.

This is another tutorial about tethering with android for different platforms and with different solutions.

Wouldn't it be great if we just could all use our Android device as a MiFi device? Just adding a wifi hotspot... Maybe for Android 2.2 release ;-).

maandag 26 juli 2010

Exclude transitive dependencies with Maven2

In some cases you might need to solve transitive dependencies by excluding them this way:
<dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-entitymanager</artifactId>
 <version>3.4.0.GA</version>
 <exclusions>
  <exclusion>
   <groupId>javax.transaction</groupId>
   <artifactId>jta</artifactId>
  </exclusion>
 </exclusions>
</dependency>

dinsdag 8 juni 2010

Wheels for my android bot

I've got some wheels for the Android Robot I'm working on. Had to find some wheels directly driven from modified servo's. Lego Technic to the rescue:

Van Drop Box

These come off a Lego Technic set with number 8479, the green scanner truck for those who are familiar with Lego (who isn't :)). You can buy the tires separatly and they also have the rims. You can look for a shop closer using the product numbers on this website.

The servo horn I used ships with the 9g servo's. They fit exactly inside this wheel. I used some tie wraps to keep it in place.

Now I'll be looking for some platform to attach these wheels to.

vrijdag 4 juni 2010

Simple and cheap Android powered robot

Android powered Robot Concept

I'm working on a cheap android powered robot. The intention is to keep it stupid and simple. If I can get my Android phone to drive all directions I'm done. All I need then is the software to control what direction to drive. I can then use the build in sensors of my Android device to decide what direction to follow, receive commands over the network, etc.

Afer some searching I found this cellbots.com blog where they already implemented this idea by using an Arduino for controlling the servo's. This still requires some basic knowledge and a hacked kernel to get the serial out of the htc ext usb connector working. Less technical approach is using Bluetooth for controlling the Arduino but that isn't cheap anymore (and still requires a custom rom for some 1.5 devices).

So I kept looking for an easier setup. And I found it on this german website. It's a great idea to use the soundcard of a computer to control servo's. Soundcards work with pulse width modulation or pwm anyway for reproducing sound so adapting this to control a servo (also pwm) should be possible.... even with an Android device. Turns out someone did that already.

Android powered Robot Setup

I tested the code from the link above and got it working. That was my first step in getting an Android powered robot. It's based on a 2 servo's setup for skid wheels. Those servo's are cheap (check ebay) and have all electronics for controlling the motor and gearing built in. All we need to do is modify them for continuous rotation. Check this link or search the web for more information on how to do this.

I ordered some cheap servo's for modifying myself. My first tests were with some more expensive servo's I don't want to hack. If that is finished I'll come back to post you my motor setup.

I will keep it simple for sure. All you need to know is how to connect 2 modified servo's, a batterypack and the stereo cable. Please keep in mind that you are doing this on your own risk. Don't do this when you don't know what you're doing! You might damage your device! This is a basic schema on how to connect all:



1) You'll need 4 AA battery's as a power supply for the servo's. Connect ground of batterypack (-) with the ground of the servo's (brown) and the ground of the two stereo channels of the headphone cord.

2) Next connect the plus (+) of the battery pack with the + (red) of the 2 servo's.

3) Don't connect the red or white wire from the stereo headphone cable with the batterypack (not even the red one :)). These 2 wires (red and white) will be used for the signal towards the servo's. So connect the red one to one of the servo's signal (orange) wire and the white one to the other servo's signal (orange) wire.

That's all for the electronics.

Android powered Robot Software

When my wheels are ready I can focus on writing some simple apk for basic movement. That will be the base to an autonome Android powered robot.

The Android device I'll be using is a HTC Hero GSM (Europe). For some features like voice recognition and bluetooth control I'll need to get a 2.1 custom rom. I might release 2 apk's, one for the original 1.5 and one for 2.1 with more options. We'll see.

This is a great article on developerworks about the android sensors.

Some features I'm thinking of:
  • Automatic Callibration. When the program is launched for the first time I only know I need to spin the wheels in the opposite direction (in case of a common dual servo setup with 2 skid wheels). What direction depends on how the servo's are wired (position of left and right channel). I can try one direction and detect if robot is going forward (that is facing camera forward). Other direction will be backward.
  • Basic collision detection. I'm not yet sure on how to implement this. I could check if the device is still moving like expected. If I detect no change in location robot can react and try to recover by turning into other direction.
  • Remote Camera View. Send captured images or video over the network (streaming) in order to see what robot is doing. Camera should be mounted in front for that (see callibration).
  • Face recognition. I can turn on face recognition and interact with recognized faces? See interaction for more about how to interact. The camera is on the back of the phone so the robot would have to turn towards the detected face first. Also face recognition is done on still images so would have to take intermediate pictures for recognizing then? Or does api provide other methods? Have to check this.
  • Interaction: It's a pitty we don't have sound to interact. Android comes with a speech engine so it could really speak to you. But we used the audio channel to drive our motors so that is no option anymore. I've been looking for alternatives and one is to use smileys like the Callo telephone robot. That combined with the face recognition could be a great solution. Also text remains. Therefore on the screen could be too small so maybe have it interact over the network.
  • Navigation using waypoints.  We have a compass to head in some direction. We also have a gps onboard so we could move based on a preset route using google maps or manually stored waypoints. About those waypoints a saw a robot somewhere that let you set the waypoints by hitting a button and then it would go over every waypoint. Can't find link though. Anyway a search on the internet will give you enough results on self navigating robots.
  • Remote control. can be realised over the network. With some simple commands like forward, backwards, left, right, stop. And maybe some text interaction as well. Would be nice to have some interaction.
  • Voice recognition is an option for 2.1 devices. It could receive the same commands for remote control over voice this way. Also some basic interaction is possible.
  • And many more... feel free to leave your ideas here.

vrijdag 30 april 2010

Android Button with both text and an Image

So ImageButton lets you create a button with an Image. And Button has text... How to combine them?

On a regular Button you can add an image on top, left, right or bottom like this:

<Button
android:id="@+id/btnId"
android:text="Some text here"
android:drawableTop="@drawable/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>

Using default Android Icons

The Android platform comes with a lot of default icons. Check this visual index of the android drawables to have an idea of what can be used.

Some examples of using these icons:

For use on an ImageButton, defined in xml:

<ImageButton
android:id="@+id/lock"
android:src="@android:drawable/ic_lock_lock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>


Or the same set in code:

ImageButton btn = (ImageButton)findViewById(R.id.lock);
btn.setImageResource(android.R.drawable.ic_lock_lock);


And another example of using these icons in your menu:

/**
* Creates the menu items
*/
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, MENU_HELP, 0, R.string.help).setIcon(
android.R.drawable.ic_menu_help);
return true;
}

donderdag 15 april 2010

Automatic updates for Android apk files

Finally :D

The android market lacks some features. One of them is automated updates for the android applications you have installed. Now you have to check your downloads for any updates on the market and update them one by one...

As a programmer for android I also didn't find a way to display the comments on the apps I have deployed. Didn't really get into it but it seems that this appbrain has them all listed.

You can search the website for any apps you want and schedule them for installation on your device.

On your device you'll have to install this appbrain app from the market that will sync with your appbrain online account ;-). Get it here:

download android appbrain from android market

And you can read a review of the app here: http://www.androidtapp.com/appbrain-market-sync/

Working with images in Android

I'll try to explain some basic image functions for the Android platform. How to get images from the camera or the device I'll explain in another post. This is more about handling image files in code.

First of all you'll want to represent your image as a Bitmap. This way you can manipulate the pixels one by one. Use the BitmapFactory to create a Bitmap from several sources. Check the API for all the options. This example creates a bitmap from file:


File sdCard = Environment.getExternalStorageDirectory();
File imageFile = new File(sdCard, "image.jpg");
Bitmap image = BitmapFactory.decodeFile(imageFile);


A big concern when working with images is the available memory. For mobile Android devices this is very limited so watch out! You have some options to avoid the java.lang.OutOfMemoryError: bitmap size exceeds VM budget exception.

Don't really load the image when you only need to know the size of it. You can set BitmapFactory.Options to only load image boundaries like this:

BitmapFactory.Options options = new BitmapFactory.options();
options.inJustDecodeBounds=true
BitmapFactory.decodeFile(imageFile, options);
int width = optins.outWidth;
int height = options.outHeight;


Sample the image if you only need to display

BitmapFactory.Options options = new BitmapFactory.options();
options.inJustDecodeBounds=false;
options.inSampleSize=10;
Bitmap bitmap = BitmapFactory.decodeFile(imageFile, options);


Recycle your bitmaps so garbage collector can come and get them

bitmap.recycle();
bitmap = null;


Remove callbacks when done displaying images with some Drawable object

drawable.setCallback(null);

dinsdag 6 april 2010

Installing Windows from bootable USB

I'm using an old Dell Inspiron 510m laptop with a broken (and therefore replaced by battery) optical drive. I could still access discs by using an optical driver shared from my network. But reinstalling Windows XP wasn't that easy! This is how I eventually got it working.

I tried this one (dutch version) before but got errors of a broken file. Probably something I did wrong myself. The guide that worked for me is found at http://www.911cd.net/forums//index.php?showtopic=22857.

1) copy all the contents of the source installation disc to a (non space) folder on your desktop. I'll reference it as C:\XPSOURCE from now.

2) plugin your USB drive. I used an old SanDisk Cruzer of 1GB. All contents will be lost so make a backup if needed.

3) download USB_MultiBoot_10.zip and unzip to run the USB_MultiBoot.cmd file in that directory. You can run it from the command line (Start > Run and enter to location of this file).

4) type "1" (without quotes) and hit enter, this will popup a utility to format your USB drive. Leave all options like they are and hit format.

5) back to the console you now type "1" followed by enter and give the path to the XP setup source files, for instance C:\XPSOURCE.

6) next type "2" and hit enter and provide the drivelleter of your USB-drive.

7) type "3" and hit enter and the bootable USB-drive will be created with the given sources.

When booting up your device from this disk you'll have to point it back to this drive each time you reboot until you've finished the installation of Windows. That is when you've successfully logged in. Only then you can start booting from the harddisk and remove the USB-drive.

vrijdag 5 maart 2010

Joomla configuration on one.com hosting

I had some issues configuring joomla for a one.com hosting.

SEF

First of all the SEF (Search Engine Friendly) urls didn't work out of the box. A quick search on the Internet learned me that I had to update the .htaccess with the one provided by joomla. In that file you also have to comment a single line. Change:

Options +FollowSymLinks

to:
#Options +FollowSymLinks


Then configure Joomla by enabling ALL 3 options for SEF. In configuration.php file that is:

 var $sef = '1';
var $sef_rewrite = '1';
var $sef_suffix = '1';


Mail

Another option that didn't work out of the box was the mail option. For this I had to contact the one.com helpdesk because the settings were different all over the Internet. They let me know that the email you're sending with has to be one hosted by them. So your gmail or any unknow address won't work. Next I had to set some settings in joomla to get that working as well. In configuration.php file:

 var $mailer = 'smtp';
var $mailfrom = 'YOUR_EMAIL_HOSTED_BY_ONE_COM';
var $fromname = 'YOUR NAME';
var $sendmail = '/usr/sbin/sendmail';
var $smtpauth = '0';
var $smtpsecure = 'none';
var $smtpport = '25';
var $smtpuser = 'YOUR_USERNAME';
var $smtppass = 'YOUR_PASSWORD';
var $smtphost = 'mailout.one.com';


This worked. The tricky part is that the contact form on the joomla website didn't even give me a warning this wasn't working. Make sure to test it!

And off course these settings can be done in the frontend as well but I'm to lazy to create screenshots.

woensdag 24 februari 2010

jvisualvm : beyond jconsole

Just discovered jvisualvm :D

IOException: Cannot run program "reg"

Running glassfish and IBM MQ7 on windows 2000 we got this error. IBM discovered this before and has this fix for us. It's a huge download for a small fix. In fact it's much quicker to simply download the missing reg.exe file (google for it) :p


WARNING: java.io.IOException: Cannot run program "reg": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
at java.lang.Runtime.exec(Runtime.java:593)
at java.lang.Runtime.exec(Runtime.java:431)
at java.lang.Runtime.exec(Runtime.java:328)
at com.ibm.mq.jmqi.internal.JmqiTools.getRegistryPropertyInternal(JmqiTools.java:1388)
at com.ibm.mq.jmqi.internal.JmqiTools$4.run(JmqiTools.java:1351)
at java.security.AccessController.doPrivileged(Native Method)
at com.ibm.mq.jmqi.internal.JmqiTools.getRegistryProperty(JmqiTools.java:1348)
at com.ibm.mq.jmqi.internal.Configuration.getProperty(Configuration.java:1202)
at com.ibm.mq.jmqi.internal.Configuration.getStringValue(Configuration.java:433)
at com.ibm.mq.jmqi.internal.Configuration.iniFileAsStreamWmqDataDir(Configuration.java:1091)
at com.ibm.mq.jmqi.internal.Configuration.findClientIni(Configuration.java:938)
at com.ibm.mq.jmqi.internal.Configuration.access$300(Configuration.java:55)
at com.ibm.mq.jmqi.internal.Configuration$1.run(Configuration.java:247)
at java.security.AccessController.doPrivileged(Native Method)
at com.ibm.mq.jmqi.internal.Configuration.(Configuration.java:238)
at com.ibm.mq.jmqi.JmqiEnvironment.(JmqiEnvironment.java:251)
at com.ibm.mq.jmqi.system.JmqiSystemEnvironment.(JmqiSystemEnvironment.java:82)
at com.ibm.mq.jmqi.JmqiFactory.getInstance(JmqiFactory.java:92)
at com.ibm.mq.internal.MQCommonServices.(MQCommonServices.java:264)
at com.ibm.mq.MQSESSION.getJmqiEnv(MQSESSION.java:139)
at com.ibm.mq.MQSimpleConnectionManager.(MQSimpleConnectionManager.java:93)
at com.ibm.mq.MQEnvironment.(MQEnvironment.java:570)
at fatass.jsf.ContextListener.contextInitialized(ContextListener.java:250)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4523)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5184)
at com.sun.enterprise.web.WebModule.start(WebModule.java:326)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:973)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:957)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:688)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1584)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1222)
at com.sun.enterprise.server.WebModuleDeployEventListener.moduleDeployed(WebModuleDeployEventListener.java:182)
at com.sun.enterprise.server.WebModuleDeployEventListener.moduleDeployed(WebModuleDeployEventListener.java:278)
at com.sun.enterprise.admin.event.AdminEventMulticaster.invokeModuleDeployEventListener(AdminEventMulticaster.java:974)
at com.sun.enterprise.admin.event.AdminEventMulticaster.handleModuleDeployEvent(AdminEventMulticaster.java:961)
at com.sun.enterprise.admin.event.AdminEventMulticaster.processEvent(AdminEventMulticaster.java:464)
at com.sun.enterprise.admin.event.AdminEventMulticaster.multicastEvent(AdminEventMulticaster.java:176)
at com.sun.enterprise.admin.server.core.DeploymentNotificationHelper.multicastEvent(DeploymentNotificationHelper.java:308)
at com.sun.enterprise.deployment.phasing.DeploymentServiceUtils.multicastEvent(DeploymentServiceUtils.java:226)
at com.sun.enterprise.deployment.phasing.ServerDeploymentTarget.sendStartEvent(ServerDeploymentTarget.java:298)
at com.sun.enterprise.deployment.phasing.ApplicationStartPhase.runPhase(ApplicationStartPhase.java:132)
at com.sun.enterprise.deployment.phasing.DeploymentPhase.executePhase(DeploymentPhase.java:108)
at com.sun.enterprise.deployment.phasing.PEDeploymentService.executePhases(PEDeploymentService.java:919)
at com.sun.enterprise.deployment.phasing.PEDeploymentService.start(PEDeploymentService.java:591)
at com.sun.enterprise.deployment.phasing.PEDeploymentService.start(PEDeploymentService.java:635)
at com.sun.enterprise.admin.mbeans.ApplicationsConfigMBean.start(ApplicationsConfigMBean.java:744)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:375)
at com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:358)
at com.sun.enterprise.admin.config.BaseConfigMBean.invoke(BaseConfigMBean.java:464)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761)
at sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.enterprise.admin.util.proxy.ProxyClass.invoke(ProxyClass.java:90)
at $Proxy1.invoke(Unknown Source)
at com.sun.enterprise.admin.server.core.jmx.SunoneInterceptor.invoke(SunoneInterceptor.java:304)
at com.sun.enterprise.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:174)
at com.sun.enterprise.admin.jmx.remote.server.callers.InvokeCaller.call(InvokeCaller.java:69)
at com.sun.enterprise.admin.jmx.remote.server.MBeanServerRequestHandler.handle(MBeanServerRequestHandler.java:155)
at com.sun.enterprise.admin.jmx.remote.server.servlet.RemoteJmxConnectorServlet.processRequest(RemoteJmxConnectorServlet.java:122)
at com.sun.enterprise.admin.jmx.remote.server.servlet.RemoteJmxConnectorServlet.doPost(RemoteJmxConnectorServlet.java:193)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:290)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:272)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
at com.sun.enterprise.web.connector.grizzly.W
WARNING: orkerThreadImpl.run(WorkerThreadImpl.java:116)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.(ProcessImpl.java:81)
at java.lang.ProcessImpl.start(ProcessImpl.java:30)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)
... 94 more


This link has a small example of code using this executable. Note that this isn't platform independent and therefor not an ideal approach. I added a print of the stacktrace in the catch blocks:


import java.io.*;

public class RegQuery {

private static final String REGQUERY_UTIL = "reg query ";
private static final String REGSTR_TOKEN = "REG_SZ";
private static final String REGDWORD_TOKEN = "REG_DWORD";

private static final String PERSONAL_FOLDER_CMD = REGQUERY_UTIL +
"\"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\"
+ "Explorer\\Shell Folders\" /v Personal";
private static final String CPU_SPEED_CMD = REGQUERY_UTIL +
"\"HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\""
+ " /v ~MHz";
private static final String CPU_NAME_CMD = REGQUERY_UTIL +
"\"HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\""
+ " /v ProcessorNameString";

public static String getCurrentUserPersonalFolderPath() {
try {
Process process = Runtime.getRuntime().exec(PERSONAL_FOLDER_CMD);
StreamReader reader = new StreamReader(process.getInputStream());

reader.start();
process.waitFor();
reader.join();

String result = reader.getResult();
int p = result.indexOf(REGSTR_TOKEN);

if (p == -1)
return null;

return result.substring(p + REGSTR_TOKEN.length()).trim();
}
catch (Exception e) {
e.printStackTrace()
return null;
}
}

public static String getCPUSpeed() {
try {
Process process = Runtime.getRuntime().exec(CPU_SPEED_CMD);
StreamReader reader = new StreamReader(process.getInputStream());

reader.start();
process.waitFor();
reader.join();

String result = reader.getResult();
int p = result.indexOf(REGDWORD_TOKEN);

if (p == -1)
return null;

// CPU speed in Mhz (minus 1) in HEX notation, convert it to DEC
String temp = result.substring(p + REGDWORD_TOKEN.length()).trim();
return Integer.toString
((Integer.parseInt(temp.substring("0x".length()), 16) + 1));
}
catch (Exception e) {
e.printStackTrace()
return null;
}
}

public static String getCPUName() {
try {
Process process = Runtime.getRuntime().exec(CPU_NAME_CMD);
StreamReader reader = new StreamReader(process.getInputStream());

reader.start();
process.waitFor();
reader.join();

String result = reader.getResult();
int p = result.indexOf(REGSTR_TOKEN);

if (p == -1)
return null;

return result.substring(p + REGSTR_TOKEN.length()).trim();
}
catch (Exception e) {
e.printStackTrace()
return null;
}
}

static class StreamReader extends Thread {
private InputStream is;
private StringWriter sw;

StreamReader(InputStream is) {
this.is = is;
sw = new StringWriter();
}

public void run() {
try {
int c;
while ((c = is.read()) != -1)
sw.write(c);
}
catch (IOException e) { e.printStackTrace(); }
}

String getResult() {
return sw.toString();
}
}

public static void main(String s[]) {
System.out.println("Personal directory : "
+ getCurrentUserPersonalFolderPath());
System.out.println("CPU Name : " + getCPUName());
System.out.println("CPU Speed : " + getCPUSpeed() + " Mhz");
}
}

donderdag 18 februari 2010

Android must have free applications

Since payed applications aren't yet supported in Belgium I can only find free applications on the market. These are my favorites:


System tools


Barcode Scanner
This one you'll need to scan the QR codes :D. You can also scan other barcodes but I didn't find much information on the net on the ones I tried.

ASTRO File Manager
The best filemanager I found for android so far.

Locale
In fact this one ain't available as a free app anymore. Only the beta was available so you'll need to look for an .apk on the web if you really want this one for free. It's a tool to change system properties based on location, date, time, etc. The properties you can change are dataconnection, wireless, flightmode, sounds, backgrounds, etc. There are several plugins available to extend the amount of events and properties.

Quick System Info
All you need to know about the system. Display processes, specs, logs, installed applications, etc.

Battery Widget
Can be placed on desktop (widget) and displays battery level. When selected an info screen with more details is shown.

Wifi Analyzer
Does exactly what you expect.

Navigation

c:geo
The best Geocaching tool I found so far. It lets you browse the caches nearby, show details of caches, show caches on the map, navigate to a cache (arrow), log when you found a cache, etc.

compass
Doesn't need much explication... you can set several styles.

GPS Status
Shows how many satellites are connected, min/max/avg speed, min/max/avg altitude, coördinates, etc.

My Tracks
Great for walkers and other outdoor sports. It tracks your route on a map. Also collects information (like GPS Status) and routes can be exported.

My Maps Editor
With this tool you can edit your google maps on your mobile.

Other
Mind Map Memo: create and edit mind maps
Pintail: get location of your cellphone by sms
SMS Backup: back up sms messages to your gmail account
Shazam: recognize music playing
Ringdroid: cut music for use as ringtone
Pricewatch Scanner: scan barcodes to find prices in the tweakers pricewatch
TVGiDS.tv: tv guide
Photoshop.com Mobile: mobile photoshop (limited)
Google Sky Map: a map of the stars
Facebook: facebook application for android
AndFTP: ftp client
A world of photo: receive and send photo's from/to all over the world
Bebbled: game like bubbles
GameBoid Lite: to play gamboy roms
Magic 8-Ball: shake to get an answer from the 8-ball
PicSay: edit pictures and add fun stuff

JavaBean properties: uppercase vs lowercase

In general JavaBean properties can be accessed by the getter method without the get and the first letter in lowercase. For instance:

public class SomeClass {
  private String test;
  public String getTest(){return test;}
  public void setTest(String test){this.text=test;}
}

When accessing from the frontend this works fine:

#{someClass.text}

But when you have a property that begins with several capitals java doesn't find it when you only lowercase the first letter like this:

public class SomeClass {
  private String xml;
  public String getXML(){return xml;}
  public void setXML(String xml){this.xml=xml;}
}

someClass.xML and someClass.XML don't work. You need to lowercase all capitals in a row:

#{someClass.xml}

Some other examples:

getXMLData => xmldata
getXMLTestData => xmltestData
getXmlTestData => xmlTestData

dinsdag 16 februari 2010

Timestamps with hibernate annotations

When you want timestamps on objects persisted with hibernate you can add callback methods that initialize these Date properties properly.

@Entity
@Table(name = "entities")    
public class Entity {
//...

  private Date created;
  private Date updated;

  @PrePersist
  protected void onCreate() {
    created = new Date();
  }

  @PreUpdate
  protected void onUpdate() {
    updated = new Date();
  }
}

donderdag 4 februari 2010

Setting up Android Development environment

Since I've got a HTC Hero Android device I started looking at developing for the android platform. It's all java based and it's all integrated in eclipse so it shouldn't be that hard for me.

I downloaded the Android SDK, unzipped everything and added this location to the system path (I'm using windows).

Next I fired up the Android SDK and AVD Manager to get it all configured...

Exception in thread "Loading Source" java.lang.NoSuchMethodError: org.w3c.dom.Node.getTextContent()Ljava/lang/String;
at com.android.sdklib.internal.repository.RepoSource.parsePackages(RepoSource.java:694)
at com.android.sdklib.internal.repository.RepoSource.load(RepoSource.java:262)
at com.android.sdkuilib.internal.repository.RepoSourcesAdapter$TreeContentProvider$1.run(RepoSourcesAdapter.java:194)
at com.android.sdkuilib.internal.tasks.ProgressTask$1.run(ProgressTask.java:135)

:D It should work out of the box :P I quickly check if I was running java 1.5 or higher but that was oké so instead of figuring out what library was in conflicht I fetched the AVD package for 1.5 directly from the web and unzipped it in the platforms folder of my android sdk installation folder. The manager recognized it so I could create an AVD for testing.

I didn't have any problems with the android eclipse plugin. After installation from the download site (https://dl-ssl.google.com/android/eclipse/) I configured it and got it running.

The virtual device really takes a long time to boot :s

donderdag 21 januari 2010

I'm calling from my HTC Hero with Android...

I'm not that into smartphones. I once had a Nokia E51 which I liked because of the small form factor. Later on I switched towards a lighter Nokia 5310 ExpressMusic.

Until today... I got a HTC Hero Android device for my birthday :D. I have to admit I really like it.


It's a wonderfull device if you're, like me, into google. I have no Office software at home since I can use google documents, this blog is google powered, I use gmail, google calendar, google maps, etc. This Android device integrates wonderfull with all these google stuff.