There's a whole bunch going on here.
The issue you describe is due to the function addToCompare being out of scope when your HTML is created, not only because it is declared locally to your onReady function, but it almost certainly will not exist at the time your HTML is processed.
You're also going to cause yourself headaches because JSP is probably not going to add quotes when it interprets addToCompare(${productData.productID}). Also, putting the ID of the element in an onClick handler is redundant since this will be set in the handler, not to mention setting onClick handlers in HTML is considered a bad practice
To solve these, you can declare the function in the document/window scope and then attach it to the click handler for your product checkbox when the document is ready.
Since you don't really need the DOM id attribute for your business logic, you might want to consider supplying the product ID as purely a data attribute - helps preserve separation between layers.
function addToCompare() {
console.log("Product ID: "+ this.id);
console.log("Product ID: "+ this.dataset.productId);
}
$(function() {
$('.productCheckbox').click(addToCompare);
console.log("Document is ready");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox"
class="productCheckbox"
id="whateverTheJSPputsHere"
data-product-id="theProductID"
/> Add to compare
JSP code (without the id):
<input type="checkbox" class="productCheckbox" data-product-id="${productData.productID}"/>Add to compare
addToCompareis defined, but never called