There are different steps on a compiler but here are the most important:
Lexical analysis
First step is the lexical analysis. Basically this steps extract tokens from java code (keywords, operators, separators, comments, variable names...)
Syntax analysis (parser)
The second step is the syntax analysis. Tokens are taken as input from lexical analysis and are combined to form expressions and instructions.
Optimization and conversion to byte code
The last macro step is converting the previous step to byte code. Here the code can be modified to be equivalent to the original code but more efficient.
Note: This process is not related only to java, but it is common to all compilers. Also compilers that don't generate an intermediate byte code but a machine code (like compilers for C or C++).
Generally there are tools to create a lexical analyzer and a syntax analyzer because this steps have many commons parts between different languages.
An open source lexical analizer is flex
A useful syntactic analizer is yacc
Both works with C and C++ that are the most used languages to create compilers (java and others too), but there are also similar alternatives for other programming languages (to create a compiler in another language, not for another language). Basically language in which a compiler is written is not related to the language the compiler compiles.