The two simplest options are a rectangular texture like you’ve been doing, or a cube map. A sphere map is more trouble than it’s worth, and makes poor use of your texture resolution; the area outside the outermost circle contains texels that’ll never be used (only pi/4, or 79%, are ever used), and that outermost circle gets mapped to only a single point on the sphere.

Using a rectangular texture, as you’ve pointed out, the last column of longitudinal triangles have texcoords that jump from something like 0.9 to 0, since you’re coming back to where you’ve started. For simplicity, let’s assume you’re mapping the texture onto a cylinder, which has the same problem without all the polar distortion of a sphere. Imagine taking a piece of paper and rolling it into a cylinder. There’s no getting around the fact that to form a closed cylinder, you’ve got to have two ends of the paper touching. In GL terms, that overlapping set of points must have two sets of vertices, one with s=0, the other with s=1, but otherwise identical. Theoretically, if you had an infinitely dense mesh, then your initial approach would work, since the last column of triangles would have texcoords ranging from 0.9999… to 0, but over an infintely thin span of space. The discontinuity only becomes apparent when you’re dealing with a discretized surface, like a triangular mesh. (Likewise, you could eliminate the extra vertices if you had control over the texcoord interpolation across a triangle; you’d have the s coord of that last column of triangles linearly march from 0.9 to 0.9999…, then abruptly jump down to 0, but even then you might get flickering of pixels at that edge that are pulled from arbitrary texels in the texture.)

Cube maps are a more elegant solution, since there’s no discontinuity in the mapping. There’s some distortion, but not nearly as bad as spherical or rectangular mapping onto a sphere. You can either define your own texcoords that at each vertex are identical to the normal (texcoord.s = normal.x, texcoord.t = normal.y, texcoord.r = normal.z), or you can just define the per-vertex normal and use a TEXTURE_GEN_MODE of NORMAL_MAP_ARB on S, T and R, which will establish the correspondence for you.

The only problem with cube mapping a sphere is actually producing the cube map; you have to come up with six square textures that meet smoothly at their edges. A smoothly wrapping rectangular texture is much easier to throw together, since only the left and right edges of the texture have to wrap. By comparison, cube maps have 12 edges where the texture must flow between faces.