Archive for category Tutorial

Solved: Mac OS X (Snow Leopard) and SVN (1.6.2)

Today I spent a few hours trying to figure out why Eclipse was unable to connect to my locally running Subversion server. I was annoyed especially because Xcode and Terminal were not having any issues.

Some background information.
- SVN is running as a daemon locally. It gets started by:
svnserve -d –listen-host localhost -r /Library/Subversion/Repository

- trying to checkout stuff using the command below via Terminal works fine
svn co svn://localhost/Project1/trunk WorkingDirName

- trying to browse the svn repository from within Eclipse 3.5 Galileo using either Subclipse or Subversive always ends up with:
svn: connection refused by the server

I tried many things but none of them helped. I googled but failed to find something relevant. Just before giving up I thought I would check what ports were open on my machine, maybe there was some conflict. There was no conflict but…
netstat -anp TCP | grep LISTEN
returned this:
tcp6       0      0  ::1.3690               *.*                    LISTEN
That’s when it dawned on me: the svnserve was binding an IPV6 address and Eclipse could not handle that!

Solution:
ps -ef | grep svnserve
kill -9 (where proc_id is the process id of your svnserve, the second number on the line)
svnserve -d –listen-host 127.0.0.1 -r /Library/Subversion/Repository/ (or wherever you’ve placed your Repository)

Done! Now svnserve is bound to an IPV4 and Eclipse can play nice too.

Cheers…

p.s. please let me know if this worked with other Mac OS / SVN versions too

, , , , , , , ,

No Comments

Mac OS and Java Me SDK 3.0

Sun have released not too long ago a Java ME SDK 3.0 that finally brings an official Wireless Toolkit Emulator to the Mac platform.

I have been dealing with SUN software for a while now and I was not expecting this to be a smooth ride. Those who’d dealt with the WTK on Windows/Linux platform are well aware of the limitations of these emulators. What I was not prepared for was to get so much clutter that would just not work more than a couple of times.

First impression: this wtk looks like the most polished emulator ever released by Sun.

Sadly, after using the thing for a few days I discovered that the old habits had not changed:

  • there is no menu entry to run an existing jad/jar pair. You have to right click on an emulator instance and then run it…
  • you cannot set-up a project starting from a jad/jar pair. There used to be an option to do this back in wtk 2.2…
  • after running a couple of apps the whole thing crashes an burns
  • when closing down the wtk a process is left lingering. Run this in a terminal:  ps aux | grep device-manager.app
  • switching the verbose mode when launching the emulator kills the whole thing dead!
  • they bundled ant 1.7.1 with the distro although ant is built in Mac OS
  • Permgen errors are thrown if you try to launch the app too often. LOL

Here’s what happened when I created a new project and tried to run it:

*** Error ***

Failed to connect to device 0!

Reason:

Emulator 0 terminated while waiting for it to register!

The same thing happens with Emulator 1 and 2 and 3 and 4 and 5 and 6 and … you get the picture.

Googling did return lots of forum posts, but hardly any answers…

So after wasting more than 2 hours on this issue I did the unthinkable: rebooted my mac! To my surprise the miracle happened during the reboot: I was finally able to run the project again.

Needless to say I am very disappointed but not surprised by the quality of this, early access, Java ME SDK.

Cheers…

, , , ,

2 Comments

Updating the UISearchBar programmatically

Today I had to update WelliBUS’s search bar programmatically because I needed to use the street picked up via GPS as my street name.

Until this point implementing the search bar seemed easy:

  • adopt a couple of protocols: UISearchDisplayDelegate and UISearchBarDelegate
  • implement a few callback methods (from the delegates listed above)
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString;
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption;
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller;
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller;
  • and implement my own filtering function
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope;

The problem I had on my hands was how to programmatically update the text in the UISearchBar and force the UISearchDisplayDelegate to call the appropriate callback methods.

Turns out it was simpler than expected (despite not being able to find a solution by googling). All that was needed was:

[self.searchDisplayController.searchBar becomeFirstResponder];
self.searchDisplayController.searchBar.text = returnString;

Cheers…

,

No Comments

Jersey and Websphere 6.1

If you landed on this page it probably means that you’ve attempted to deploy a Jersey RESTful web service in IBM’s Websphere app server.
First of all: what were you thinking?!?

Secondly: it probably wasn’t your decision and you just need to make it work and move on. That was our case anyway…

So rather than bore you to death with how we ended up debugging the JVM and discovering that a java.lang.TypeNotPresentException is thrown when calling class.isAnnotationPresent from within the cores (com.ibm.oti.reflect.AnnotationHelper.getAnnotation) of the IBM J9 JVM rather than a plain true / false, I will just give you a bullet list of the things that need to happen to keep Websphere happy.

  • Get your versions right! Jersey 1.0.3 and Websphere AS 6.1.0.25 (including 6.1.0.25 Fix Pack for Web Services) (Getting here is a blog post in itself and I will not do it here)
  • Make sure that the enterprise app that contains your Jersey resources uses “Classes loaded with parent class loader first” and “Single class loader for application” (That is in your application’s “Class loading and update detection” section.)
  • In your web xml configure the Jersey servlet to search for resources using ClassNames rather than packages. Basically make sure your web.xml looks similar to what I have below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        <servlet>
		<servlet-name>Jersey Web Application</servlet-name>
		<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
		<init-param>
			<param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
			<param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
                </init-param>
		<init-param>
			<param-name>com.sun.jersey.config.property.classnames</param-name>
			<param-value>
				net.tmro.MyRESTfulResource
			</param-value>
		</init-param>
		<load-on-startup>10</load-on-startup>
	</servlet>
 
	<servlet-mapping>
		<servlet-name>Jersey Web Application</servlet-name>
		<url-pattern>/json/*</url-pattern>
	</servlet-mapping>
  • Okay, some clarification: the reason ClassNamesResourceConfig is used rather than PackagesResourceConfig is that when the packages are browsed for the actual @Path annotated classes an actual jar browsing is done which throws and swallows a nasty SecurityException… I invite you (more like dare you) to try using ClasspathResourceConfig and let me know if it works.

Now go ahead and give this a try… don’t forget to let me know if it worked or failed for you… Good luck!

Cheers….

No Comments

iPhone build error

I had to deal with the same problem twice in the past 2 days so I decided to put together this little post explaining what one needs to do when they see an error message like this:

error: syntax error before ‘AT_NAME’ token
error: syntax error before ‘}’ token
fatal error: method definition not in @implementation context
Build error message

Build error message

Basically, what happens here is that the target for my iPhone application is using the wrong C/C++ Compiler version.

Here’s the fix:
Step 1 double click the target (or right click Get Info) and change the Compiler version to GCC 4.0

Compiler Version changed to 4.0

Compiler Version changed to 4.0

Step 2 add 2 new build setting conditions (one for the simulator and one for the device)

Build Setting Conditions

Build Setting Conditions

Step 3 Set the values to GCC 4.2

Final settings

Final settings

Hit the magic Cmd + B and you should now have a project that builds (or at least no longer complains about the syntax error above.

Cheers…

No Comments

Jersey 1.0.2 JSON and JAXB

In a previous post I explained how to unit test JAX-RS. Let’s now have a look at a more complex example: implementing RESTful webservices using Jersey 1.0.2.

To get RESTful web services (JAX-RS) that produce JSON output using Jersey you have to get the following libraries:
1. Jersey 1.0.2 (see the dependencies here for a web application. Make sure you get: jersey-server.jarjersey-core.jarjsr311-api.jarasm.jar)
2. JAXB 2.1 (jaxb-impl.jarjaxb-api.jar) If you run into problems later just check that you are running jaxb 2.1.10. The 2.1.10 jaxb-impl.jar provides support for the natural jsonconfiguration.
3. JSON-lib 2.2.3 (json-lib-2.2.3-jdk15.jar) You will use this later to construct a MessageBodyWriter Provider that outputs JSON content…
Let’s start setting up the whole lot.
WEB.XML
In your web application’s web.xml make sure you’ve hooked up Jersey:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<servlet>
  <servlet-name>My Jersey Web Application</servlet-name>
  <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
    <param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
  </init-param>
  <init-param>
    <param-name>com.sun.jersey.config.property.packages</param-name>
    <param-value>net.tmro.demo.json;your.packages;separated.by.semicolons</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>My Jersey Web Application</servlet-name>
  <url-pattern>/webappjson/*</url-pattern>
</servlet-mapping>
1. The PackagesResourceConfig param enables your to do automatic discovery of your relevant classes as long as you provide the packages location.
2. The url pattern is the endpoint where your resources will be made available.
The RESTful resource
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package net.tmro.demo.json;
 
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
 
@Path(/myresource”)
public class MyResource {
 
	public MyResource() {
	}
 
	@GET
	@Produces(value=MediaType.APPLICATION_JSON)
	@Path(/getsomething”)
	public MyComplexObject getSomething(@QueryParam(“idOfSomething”) String id) {
		//your complex object can expose primitive data types, objects as well as collections.
		//you are not required to do anything fancy as long as you implement
		return new MyComplexObject(id);
	}
}
To get something your endpoint will now look like: http://yourserver:port/appcontext/webappjson/myresource/getsomething?ifOfSomething=id The parts in bold represent what you’ve defined so far.
The @Get annotation specifies what type of requests are handled by this method.
The @Path allows you to discriminate between several methods that you might have in this resource class.
If in your @Produces you were to specify a MediaType.APPLICATION_XML you’d get a neat xml response when pointing your browser at the endpoint above. But what we actually want is a JSON message. So let’s continue.
JSON MessageBodyWriter
The xml returned by our resource needs to be converted into JSON format. I used the json-lib that I mentioned above. Here’s the code for it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package net.tmro.demo.json;
 
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
 
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.*;
import javax.ws.rs.ext.*;
 
import com.sun.jersey.spi.resource.Singleton;
 
import net.sf.json.JSONSerializer;
 
@Provider
@Singleton
public class MyEntityProvider implements MessageBodyWriter<object> {
	//the json serializer used to write out objects to the output stream
	private final JSONSerializer serializer = new JSONSerializer();
 
	public long getSize(final Object t, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
		return -1;
	}
 
	public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
		return mediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE);
	}
 
	public void writeTo(final Object t, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<string, Object> httpHeaders, final OutputStream entityStream) throws IOException, WebApplicationException {
		entityStream.write(serializer.toJSON(t).toString().getBytes());
	}
}
Not much going on here: we implement the MessageBodyWriter interface and we only use this entity provider to handle JSON mime types.
Note that the class is annotated @Provider so make sure that you have specified this package in your web.xml deployment descriptor.
Returned objects
The only thing that is still missing is the actual object that is returned. Here is an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package net.tmro.demo.json;
 
@XmlRootElement
public class MyComplexObject extends AnotherObject {
 
	//fields: primitive data types, objects and collections. everything gets serialized unless
	//marked as transient
 
	public MyComplexObject(String id){
	[..]
	}
 
	//getters and setters
}
The only thing that I have done really is to annotate it with @XmlRootElement. If you have properties that you do not want to return simply annotate them with @XmlTransient.
Now build and deploy your application and keep an eye on the log. You should see:
- Scanning for root resource and provider classes in the packages:
and then a list of your packages defined in the web.xml
Root resource classes found:
followed by your Resource class.
Provider classes found:
followed by the entity provider that you have implemented.
To test just point your browser to the url I described above and your browser should prompt you to save some streamed data. Open it with a text viewer and you should be able to see your JSON response.
Cheers…
Before I conclude: if you’ve tried to get things going and ended up with something like this:
com.sun.jersey.spi.container.ContainerResponse write
SEVERE: A message body writer for Java type, class [..], and MIME media type, application/json, was not found
com.sun.jersey.server.impl.application.WebApplicationImpl onException
SEVERE: Internal server error
javax.ws.rs.WebApplicationException
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:241)
you might want to check that your jaxb and json lib versions are OK and that the MessageBodyWriter implementation is picked up when you start your web app…
I would be interested to find out if you managed to find a way to NOT implement the MessageBodyWriter but still get JSON output.

, , , , , ,

5 Comments

Selecting a contact on the iPhone

Today I had to load a Contact browser in my iPhone application I have to say I was surprised to see how easy it was!

The first thing that I thought about was to… google for it. Sure, I didn't know this side of the API and I imagined I would have to query some address book database and then build a table view using my query results as datasource. And guess what, this can actually be done very easily.
 
Luckily I looked deeper in the SDK API and found that there is a Navigation Controller already available that does everything I need.
Here are the steps I had to follow in order to implement this functionality.

1. Imports
Add the AddressBook and AddressBookUI frameworks to my project (control click the Target and then Get Info and Add Framework)

2. Set up the controller
Create an instance of ABPeoplePickerNavigationController on the control that you want to trigger the contact selection.

3. Set up a delegate
The controller will make a series of callbacks which is why you need to implement a protocol that is the actual delegate for the above controller. The delegate is ABPeoplePickerNavigationControllerDelegate and the callback methods are below:
– (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;  
Gets called when the user taps the Cancel navigation button. Here you should dismiss the person picker navigation controller. See point 4 below.

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person;
This is the place where you get access to the actual section therefore you have to make sure you use the person reference to extract the data you need. See point 5 below. If you want the user to get detailed information about the selected user return YES, if you're only after the name and want to limit navigation just return NO.

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier;
This is where you take action if the user taps various properties such as phone number, email, etc If you are simply after the person's name like I was simply return NO.

4. Loading the controller and dismissing it
You load the ABPeoplePickerNavigationController using your current navigation controller's presentModalViewController method. You implement this wherever you handle the tap / action on the triggering control.
When the user taps cancel you dismiss the people picker controller via the dismissModalViewControllerAnimated method belonging to your controller. You implement this in the peoplePickerNavigationControllerDidCancel method above.

5. Extracting the relevant information
The ABRecordRef pointer gives you access to the contacts details. Here is how you'd extract the contact's first name:
 
  CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);

Notice the  kABPersonFirstNameProperty constant. There are many more like this one that enable you to get the data you need. Here is the complete list:

kABPersonFirstNameProperty
kABPersonLastNameProperty
kABPersonMiddleNameProperty
kABPersonPrefixProperty
kABPersonSuffixProperty
kABPersonNicknameProperty
kABPersonFirstNamePhoneticProperty
kABPersonLastNamePhoneticProperty
kABPersonMiddleNamePhoneticProperty
kABPersonOrganizationProperty
kABPersonJobTitleProperty
kABPersonDepartmentProperty
kABPersonEmailProperty
kABPersonBirthdayProperty
kABPersonNoteProperty
kABPersonCreationDateProperty
kABPersonModificationDateProperty

Don't let the CFString data type scare you. You can simply cast to a (NSString *) and use it… This is just one of the interchangeable data types, but that will be another post.

Cheers…

No Comments

UITabBarController and multiple instances of UITableViewController

Here comes another post from the series “note to self”…

Imagine you have a UITabBarController and you wish to have two very similar UITableViewControllers nested within (as different tab items). If the difference between the two TVCs is simply a matter of configuration (e.g. datasource) then you should simply point Interface Builder to the same class. You need not worry, different instances of your TVC will be created for you.
This comes in handy especially when you use different tab items just because your data is organized differently on each of the tabs.
I just thought I’d share this with you since I *hate* seeing duplicate code!
Cheers…
p.s. the more I master the dynamic UI generation the more comfortable I am using the IB. Isn’t this a bit ironic and paradoxical?!

1 Comment

Unit Test JAX-RS using Java 6 and JUnit 4

Today I was amazed to discover that Unit testing JAX-RS resources with JUnit 4 and Java 6 is insanely easy.

Have a look at the example below and then read the description underneath if things are not clear enough already.

import static org.junit.Assert.*;

import java.io.*;
import java.net.*;

import javax.ws.rs.*;

import org.junit.*;

import com.sun.jersey.api.container.httpserver.HttpServerFactory;
import com.sun.net.httpserver.HttpServer;

@Path("/hellotest")
public class MyResourceTest {

    private static final String LOCALHOST = "http://localhost:9998/";

    private static HttpServer server;

    @GET
    @Produces("text/plain")
    public String testSystem(){
        return "Hello. This is a test";
    }

    @BeforeClass
    public static void setUp() throws Exception{
        System.out.println("Creating server");
        server = HttpServerFactory.create(LOCALHOST);

        System.out.println("Starting server");
        server.start();

        System.out.println("HTTP server started");
        System.out.println("Running tests...");

        testResourceAtUrl(new URL(LOCALHOST + "hellotest"));
    }

    private static String testResourceAtUrl(URL url) throws Exception {

        try {
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            connection.setRequestMethod("GET");
            connection.connect();

            InputStream inputStream = connection.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String firstLineOfText = reader.readLine();//you can also read the whole thing and then test
            System.out.println("Read: " + firstLineOfText);

            System.out.println("System was initialized correctly. About to run actual tests...");

            connection.disconnect();

            return firstLineOfText;

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        throw new Exception("could not establish connection to " + url.toExternalForm());
    }

    @Test
    public void testMyMethod() throws Exception {
        String activationText = testResourceAtUrl(new URL(LOCALHOST + "myresource"));

        //TODO test here

    }

    /**
    * Destroy the server
    */
    @AfterClass
    public static void tearDown() throws IOException{
        System.out.println("Stopping server");
        server.stop(0);
        System.out.println("Server stopped");
    }

}

So here’s what the code above means:
1. @Path(”/hellotest”) The unit test itself is set up as a resource so when the tests are run we can check that the system is working by consuming the resource defined by testSystem()
2. Java 6 allows us to set up a HTTP server very easily using  HttpServerFactory.create(LOCALHOST) This way we simply go ahead and send HTTP requests without having to worry about 3rd party libs and setting up mock HTTP servers.
3. testResourceAtUrl(new URL(LOCALHOST + “hellotest”)) does the hard work: it requests the resource from the location that we specify in the method call.  
4. put your actual test data in the placeholder ;)

Of course this is a simplified test, and it is meant just to show you how easy it is to test your RESTful webservices. How would you make this better?

Cheers…

, , ,

2 Comments

Windows file paths on *nix systems

Yesterday I amused myself when I re-discovered that I had to deploy a web application that was pointing to external files using windows style absolute paths rather than relative paths.

Imagine this scenario:
1. You are running a *nix system. Mac OS, Linux (Ubuntu) etc
2. You have an existing web application that references some sort of external resource (e.g. logging configuration file), but the path to this resource is windows style. e.g. C:/logging/config.xml
3. This web application used to run just fine on a server running on Windows (e.g. JBoss) but now that you have deployed it to your new OS the path no longer makes sense…

You have three choices:
1. bitch at those who used absolute paths in the web application and ask them to fix it.
2. change the web application to reference some sort of relative path
3. WOW: create a c: folder in your JBoss bin folder.

I kid you not! This is actually possible… funny as hell, but still possible.

If you are on Mac OS, the trick is to create the c: folder from the Terminal rather than Finder. Finder will not allow ":" in the name of a folder. So fire up terminal, cd to the JBoss/bin folder and run :

>mkdir c:

Now copy into this folder the resources that you need. e.g. logging/config.xml and you are ready to go.

Let me know if this worked on your OS.

Cheers…  

,

No Comments