Sunday, June 24, 2012

Wifi sync troubleshooting for iPhone

I just had to post this.

 When iOS 5 came out a while back (months ago), I had tried to use WiFi syncing. I never succeeded. For some reason, when my iPhone (4S) was plugged into the wall, and both the iPhone were connected on my only wireless network, the phone would never show up in the iTunes device list. Also, on the iPhone, when I went to Settings / Wifi syncing, the Synchronize button was greyed out.

 What was even weirder was that I could see my iPhone's music as a shared library on iTunes on my Mac, AND, I was also using my iPhone Remote app to control iTunes on the Mac remotely. But, WiFi syncing wasn't working.

 I read many troubleshooting threads either on the Apple official forum or elsewhere. Nothing worked, so I left it at that.

 Today, I must have spent another 2 hours on the problem, same result. That is, until I changed one of the variables : the network. Instead of trying to connect both the Macbook and the iPhone through my wireless router, what I did was to create an Ad-Hoc network on the Macbook, and tried to make WiFi syncing work through that network. IT WORKED !

 If you want to try it :

 Apple menu / Preferences / Network, then click on the list-box showing your current WiFi network (right section), and select "Create a network". Name that network "Test Network", and click OK. Now, on your iPhone, go to the Settings app and select that new network for WiFi. I may have restarted iTunes, or maybe not, but the iPhone showed up in the Devices section, and the WiFi sync kicked in. I then reconnected the Macbook and iPhone to my original WiFi network, and the iPhone still showed up in the Devices section. 

It's like using that other network cleaned something up in the Macbook's or iPhone's internals or something. Hope it helps someone.

Tuesday, May 22, 2012

Java: NoClassDefFoundError for a class inside a jar in your classpath

Here's an obvious one that took me a lot longer to figure out than I wanted.

I have a class (A) that uses another class (B) that sits within a jar.

To launch the class, I used :

java -cp full/path/to/B.jar:./ fully.qualified.name.for.A

I get the NoClassDefFoundError exception for B at the line where I try to instantiate it.

- Made sure the path to B.jar was correct
- Opened up the jar and made sure B was in there, in the correct directory.

Turns out that the jar had been made on Windows with a Manifest classpath in Windows format (C:\etc...) that didn't exist on the Linux machine I was trying the class on.

I rebuilt the jar, making sure the classpath was empty in the manifest, and instead referred to the classes that were in that earlier manifest classpath in the -cp argument.

Problem solved.

Wednesday, March 28, 2012

Macs, Remote Desktop and keyboards

I have a little project I'm developing in Java on top of my real job.

I usually do my development directly on my Windows machine, but I often connect through Remote Desktop from my Mac.

I have a French keyboard Mac, and the keyboard on the Windows machine is also French.

Of course, when you develop Java programs, the following keys are used extensively: {}[].

The problem is that the key combinations required on the Mac to produce these characters aren't sent correctly to the Windows PC through Remote Desktop. The quickest way to circumvent this problem is simply to copy and paste braces or brackets from existing code. Quite annoying.

I remember having searched for this problem before, and at that time I had not found anything.

Today I did : Ctrl + Alt.

It turns out that, for example, to type a { on my Mac, I have to type Alt-7, but when I'm in Remote Desktop, I need to use Ctrl-Alt-è.

Here are a couple of mappings that are useful :

To get a Type
{ Ctrl-Alt-è
} Ctrl-Alt-à
[ Ctrl-Alt-^
] Ctrl-Alt-ç

I imagine that for other languages, the key combinations would be different, but I'm convinced that you'll find them with Ctrl-Alt :-)

Sunday, January 8, 2012

OpenDNS, Dyndns, and DNS cache on Windows

I hope this helps someone in the future.

I've been using Dyndns.org for probably more than 10 years in order to be able to access my servers at home while I'm out of the house. Since most home routers have been supporting Dyndns for many years, this is a really simple setup.

In the last year or two, my kids have grown up and are now at the age where they use the internet on a daily basis, and so I've decided to use OpenDNS for my DNS needs, which has the added bonus of having url filters built in, so that I can minimally control what web sites my kids have access to.

I'm also a developer, and I have a machine set up at my buddy's house to host a web site. Since he has a dynamic IP also, I set up his own Dyndns account so that I can access the site from my home.

What I started experimenting was that when my buddy's ISP changed his IP, I couldn't access the site anymore using the Dyndns name.

As it turns out, OpenDNS' DNS tables are not updated right away when an IP address changes. After a bit of research, I found another service, DNS-O-MATIC, which allows you to tell OpenDNS that your IP has changed. So I set up an account there for my buddy, added dns-o-matic to his ddclient, and it worked fine.

Except for my Windows machines.

When my buddy's IP would change, ddclient on his machine would contact DNS-O-MATIC to request the OpenDNS IP change. At that point, if I was at home on a Linux machine and I tried to ping the Dyndns name, it would return the new address. However, on my Windows 7 machine, I'd still get the old address.

More Google.

It turns out that Windows has a DNS cache running by default. This cache, it seems, gets reset every 24 hours. If you disable that cache, then your system will query OpenDNS everytime you request a URL, but at least you'll get the latest one.

To enable/disable the cache, Start, Run..., and type "services.msc" and Enter. Then look for DNS Client, and disable/enable it.

With DNS cache enabled, you can also flush the current cache by typing the following in a command window : ipconfig /flushdns.

Finally, you can see the list of cached URLs by typing ipconfig /displaydns.

Friday, December 9, 2011

Reading a properties file, in an Axis2 web service, from the file system...

For those with some experience with Axis2 web services, you know that the axis2 application gets installed, as all Tomcat applications, in the <TOMCAT_ROOT>/webapps directory.

The axis2 app itself has a WEB-INF sub-directory, which itself contains these :

- classes
- conf
- lib
- modules
- services

I've been coding a few web services lately which use some java libraries (jars). I've found that the easiest way for the web services to get access to those libraries is to install all these jars in the WEB-INF/lib directory.

I then came to this requirement : one of the classes in one of the libraries needed to get its configuration information from a Properties file.

When I was coding within the Eclipse environment, that was easy enough, I just put the configuration file in my Eclipse project's root, and then used the following code :

String filename = "config.properties";
Properties props = new Properties();
props.load(new FileInputStream(filename));

Nothing new here, and it worked like a charm.

The problems started when I packaged that class into a library, and tried to use it from some web service installed in Axis2. The file couldn't be found anymore, or, more precisely, I had no idea where to put the file.

Note that I didn't want to put the file within the AAR archive : I wanted the file to be outside the web service's archive because I wanted to configure the application from a text file that could be easily changed with a text editor directly on the target server. I wanted to avoid having to rebuild the archive everytime I wanted to install somewhere where I needed different properties.

It turns out that all that's needed is this :

- put your properties file in the WEB-INF/classes directory or your Axis2 installation, or to be more precise, in <TOMCAT_ROOT>/webapps/axis2/WEB-INF/classes
- in your code, use this.getClass().getResourceAsStream(), like this :

String filename = "config.properties";
Properties props = new Properties();
InputStream isr = this.getClass().getResourceAsStream("/"+filename);
if (isr != null){
  InputStreamReader isrProperties = new InputStreamReader(isr);
  props.load(isrProperties); 
}

Did you notice the "/" in front of the filename on the third line ?

This means look in the root of the classpath. And the root of the classpath, in an Axis2 web service environment, is <TOMCAT_ROOT>/webapps/axis2/WEB-INF/classes.

Hope this helps.

Monday, August 15, 2011

Getting a Canadian iPhone to work with an AT&T GoPhone SIM card, Conclusion

Back from vacation in Virginia Beach, and I thought I'd let all know that the AT&T SIM card I put in my Canadian iPhone 3G has worked flawlessly for the complete duration of my trip.

I had read on different sites that AT&T might deactivate the SIM, supposedly because they could detect that my phone was canadian, but no such thing happened.

So, I definitely recommend using the GoPhone SIM card in the iPhone 3G. As for the iPhone 4, it doesn't work as far as I can tell.

Friday, August 5, 2011

Getting a Canadian iPhone to work with an AT&T GoPhone SIM card, Part 5

Well, I'm now on highway 87 driving down to VA beach, and although coverage is spotty at best, I can now confirm that the GoPhone SIM card works in my jailbroken and unlocked iPhone 3G.