Category Archives: Software

Creating an array of generics in Java

I was messing around with creating a generic Bag collection in Java that’d be backed by an array. It turns out that you can’t do this for a number of interesting reasons…

In Java (and C#), arrays are covariant. This means that if Apple is a subtype of Fruit, then Apple[] will also be a subtype of Fruit[]. Pretty straightforward. That means this will compile:

Apple[] appleArray = new Apple[10];
appleArray[0] = new Apple();
Fruit[] fruitArray = appleArray;    //Spot the problem?

If you’re like me, you didn’t think too hard about this, and assumed you could do the same with parameterized types, i.e. generics. Thanksfully you can’t, because that code is unsafe. It will throw an ArrayStoreException at runtime which we’d have to handle.

Wouldn’t it be great if we could guarantee type safety at compile time?

Generics are safer

Unlike arrays, generics are invariant, which means that Apple being a subtype of doesn’t matter: a List<Apple> is different than a List<Fruit>. The generic version of the code above is illegal:

Vector<Apple> apples = new Vector();
Vector<Fruit> fruits = apples;       //Compile-time error

You can’t cast it, either:

Vector<Apple> apples = new Vector();
Vector<Fruit> fruits = (Vector<Fruit>)apples; //Still a compile-time error!

By making generics invariant, we guarantee safe behavior at compile time, which is a much cheaper place to catch errors. (This is one of the big reasons developers get excited about generics.)

So why are arrays and generics mutually exclusive?

In Java, generics have their types erased at compile time. This is called type erasure. Type erasure means a couple of things happen at compile time:

  • Generic types are boiled down to their raw types: you cannot have a Derp and a Derp<T> in the same package.
  • A method that has a parameterized type overload won’t be compile: a class with methods popFirst(Derp<T> derp) and popFirst(Derp derp) won’t compile.
  • Runtime casts are inserted invisibly by the compiler to ensure runtime type safety. (This means there’s no performance benefit to generics in Java!)

Java’s implementation of generic types is clumsy, and was done to maintain backward-compatibility in the bytecode between Java 5 and Java 4.

Other high-level languages (like C#) implement generics very differently, which means none of the three caveats above apply. Generics in full-stack implementations do net performance gains along with those type-safety guarantees.

To recap, in Java:

  • Arrays require type information at compile time
  • Generics have their types erased at compile time

Therefore you cannot create arrays of parameterized types in Java.

Further reading

How to fix broken iCloud photostream sync on Windows

Symptom

  • Your iPhone is set to back up your photos to iCloud
  • iCloud on your Windows machine is configured to download your photos
  • iCloud isn’t downloading your photo stream.

Fix

  1. Open the Task Manager by hitting Ctrl+Shift+Esc
  2. Click the Processes tab
  3. Click Name to sort the processes by name
  4. Find the Apple Photostreams Uploader and Apple Photostreams Downloader processes. End both of them.
    • In Windows 7, these will be called ApplePhotostreamsUploader.exe and ApplePhotostreamsDownloader.exe
  5. Hold down your Windows key, and hit R to open a Run prompt
  6. Type %appdata% and hit Enter
  7. Open Apple Computer > MediaStream
  8. Delete everything in the directory
  9. Log out of your Windows account, and log back in (or just reboot, if you find that easier)
  10. Once you’ve logged back into your Windows account, open the iCloud control panel again
  11. If the Photos checkbox is empty, check it
  12. Click Options, and make sure the photo options are configured how you want them
  13. Click Apply

In a few moments, your photos should start downloading.

Notes

iCloud isn’t very smart about a great many things. Here are a few:

  • If you changed the location of your downloaded photos, it will redownload what it can, creating duplicates.
  • In the iCloud 2.x days, your downloads and uploads were usually split into a Downloads and Uploads directory, and you could change the directories if you wanted. That’s not true anymore. Instead, iCloud 3.x creates a “My Photo Stream” directory, and sticks your downloads in there. Anything you’ve shared with other people, or that other people have shared with you goes into “Shared”. If you want to push a photo from your computer to iCloud, put it into Uploads


If you found this post useful, please consider donating $2

How to install iCloud on Windows Server

Symptom
iCloud sync stops working, or you get an error message on startup that says: The procedure entry point _objc_init_image could not be located in the dynamic link library objc.dll’ and will not start.

Cause
Apple has configured newer versions of iCloud (version 3+, I believe) to only work on Windows 7 or 8, but there’s no reason you can’t use it on Windows Server operating systems.

Fix
You’ll need about 3 minutes, and two utilities.

  1. Install 7-zip.
  2. Install Orca, a Microsoft-provided MSI editor.
    • Orca is bundled with the Windows SDK, and getting it out of that bundle isn’t straightforward, so I’ve extracted it, and zipped it up so you can get it as a standalone program.
  3. Download the iCloud control panel installer, if you haven’t already
  4. Open iCloudSetup.exe with 7-zip.
    1. Right-click it
    2. Select 7-zip > Open with 7-zip
  5. Extract the appropriate version of iCloud somewhere (usually this is iCloud64)
  6. Open Orca, and open the iCloud MSI you just extracted
  7. Go to the LaunchCondition table
  8. Change this line:
    • From: (VersionNT >= 601) AND (MsiNTProductType = 1)
    • To: (VersionNT >= 601) AND (MsiNTProductType = 3)
  9. Save and quit

You should then be able to install iCloud on your Windows Server OS using the MSI you just modified.