The software is written and compiled for a JVM that takes its own platform independent bitcode, so there's nothing that intrinsically ties a particular class file to a particular machine.
That said, the software used to create the JVM is platform dependent. It handles the conversion from the JVM to the actual machine. Therefore, java is platform independent assuming someone has implemented JVM software for every platform, and on most platforms this is true.
You're asking about several aspects at the same time.
The language spec itself is in fact platform-independent. That is, there is no aspect of the language itself which relies on, or ties the model to, any machine platform. Consider for example the use of a sizeof operator in C/C++, which shows that in order to compile the program code itself must know certain properties of the CPU. The core Java language has no dependencies of this sort, and the bytecode produced will run, with some notable exceptions, on any platform.
Any platform, that is, that has a JVM available. In this respect, Java isn't radically different from any other language that requires a platform-dependent interpreter (ksh, Perl, Python, etc.). It is different from C/C++, though, in which code that is compiled to run on one platform will not run on another. You have to compile C/C++ on a per-platform basis. Since the compiler creates an executable object that knows how to run on the platform at hand, a separate interpreter is unnecessary.
Make visible what, without you, might perhaps never have been seen. - Robert Bresson
One can even generate the on-the-JVM-executable-byte_code manually without using any compiler. It is the JVM on that platform (OS AND Processor-CPU) actually, that transforms it to the hardware level. So JYM is sort of an emulator, which is written for that platform (OS + CPU).