Not disposing your resources properly is an error. Your language should make it as easy as possible to make this impossible (or at least highly unnatural).
> The only exceptions are C++ RAII wrapper classes, which are designed to have magical destructors.
They are the (only?) correct form of resource management: automatically clean it up when you're done with it.
> C#'s using(), Python's with statement, Haskell's with* functions -- they're all designed to solve the problem that a generic garbage collector doesn't and shouldn't, which is "I need precise control over the lifetime of this resource allocation". Java doesn't have such a mechanism, but then, Java doesn't have much of anything for a supposedly high-level language.
using() is the same as try{}finally{}, which Java does have. The problem with these is that you can forget them.
The problem with garbage collection is that it seems to always come with the baked-in assumption that memory is the only resource that really matters, so handling of other resources is a bolted-on afterthought. GC impeded correctness, not because of anything fundamental, but because it is seen to substitute for proper resource management.