Side-channel vulnerabilities in software are caused by an observable imbalance in resource usage across different program paths. In this paper we demonstrate that just-in-time (JIT) compilation, which is crucial to the runtime performance of modern Java virtual machines (JVMs), can be leveraged to induce timing side channels. We present a technique for creating dynamic, JIT-based side channels and using them to learn values of predicates about secret inputs. Our technique includes a mechanism for priming the state of the JVM to trigger certain runtime JIT optimizations. The timing of subsequent method calls then leaks information about the values of predicates (branch conditions) on inputs. We define two attack models and five vulnerability templates based on the optimizations performed by state-of-the-art JIT compilers. Applying these templates to Java methods gives rise to various types of runtime-behavior-dependent side-channel vulnerabilities. We use symbolic execution to automatically generate input values that prime the JVM into states that foster such vulnerabilities. We evaluate our technique on three widely used classes from the Java standard library: java.lang.Mat}, java.lang.String, and java.math.BigInteger. We show 18 attempts to induce JIT-based vulnerabilities, including successful and unsuccessful ones, and discuss the results in detail. The significant amount of information leakage achieved demonstrates the viability and potential of this class of attacks.