AESEngine.java, from BouncyCastle, uses table lookups as does aes_x86core.c, in OpenSSL. But per Cache-timing attacks on AES table lookups like what OpenSSL and BouncyCastle are doing are vulnerable to timing attacks. So why would they use them?
I believe that it is for two reasons:
Nontable based implementations of AES are possible, but (assuming you don't have AES-NI or something similar) are significantly slower than table based implementations (perhaps $10\times$ to $20\times$ slower)
For a lot of uses, timing attacks aren't particularly relevant (as either the attacker can't get the start/stop times, or can't get them to the precision needed to actually perform such an attack against AES)
Remember, when we deal with side channel attacks, there are a number of attack models possible:
At the simplest level, the attacker gets no information about the encryption process; he can (possibly) submit chosen plaintexts and ciphertexts, but the encryption operation looks like an abstract Oracle
The attacker might get some information (to some precision) about how long the encryption process takes
The attacker might also get some information about the memory accesses that the encryption process tables (cache-based side channel attacks)
The attacker might get some information about the state of the electronic gates of the device during the encryption process (DPA, EM-based side channel attacks)
The attacker might be able to cause a miscomputation during the encryption process (Fault Cryptanalysis)
The attacker might get unfettered access to the entire encryption process (White Box Cryptography)
The countermeasures needed as you go down the stack become increasingly expensive; it sounds reasonable that an implementation will say "we'll go down this far and no farther"