Вы получаете код JSP, который выполняется на сервере, смешанный с кодом JavaScript, который выполняется на клиенте. Фрагмент <%=columns.get(j++)%>
выполняется один раз на сервере, и цикл JavaScript вокруг него не имеет значения на данном этапе. Когда он приходит к клиенту, тело цикла просто говорит colArray[i] = "first entry";
, что, конечно, помещает одну и ту же строку в каждый элемент массива.
Вместо этого вам нужно выполнить цикл на сервере, например:
<% for (int i=0; i<columns.size(); i++) { %>
colArray[<%= i %>] = "<%= columns.get(i) %>";
<% } %>
Мои навыки JSP ржавые, и синтаксис может быть другим, но я надеюсь, что вы поняли.
Редактировать: Как было отмечено в комментариях, вам нужно ОЧЕНЬ быть очень осторожным, избегая экранирования чего-либо в этих строках, что может привести к их интерпретации как код JavaScript (наиболее заметные кавычки) - особенно они содержат пользовательский контент. В противном случае ваше приложение остается широко открытым для межсайтовых сценариев и подделка межсайтовых запросов атак.