Dificuldades com UTF8 e Glassfish: caracteres especiais sendo convertidos para html entities?

. . Pessoal, peguei um projeto legado aqui pra dar manutenção. Sou programador há muitos anos, mas não tenho experiência quase nenhuma com Java, principalmente pra web. O projeto estava escrito em ISO (latin1) e eu preciso convertê-lo para UTF8.
. . Até agora converti os fontes todos usando o “recode”, ajustei as meta tags nos “layout.jsp”, coloquei as instruções corretas no glassfish-web.xml:

<glassfish-web-app> <parameter-encoding default-charset="UTF-8" /> </glassfish-web-app>
E no web.xml:

<jsp-property-group> <url-pattern>*.jsp</url-pattern> <page-encoding>UTF-8</page-encoding> </jsp-property-group>
. . Com isso o GlassFish finamente passou a respondeu com o cabeçalho correto. Mas os caracteres continuaram aparecem incorretos na página, então eu dei uma olhada com mais calma e vi que o que vai pro HTML na verdade são os “htmlentities” dos caracteres errados. É como se ele pegasse um caractere UTF8 (dois bytes), interpretasse os bytes separadamente e os codificasse como entities. Um exemplo: “mãos”.
. . O caracter “ã” (que seria 0x00E3 em UTF, ou “0xC3 0xA3” quando em hexa) vira o equivalente em entities ao %C3 e %A3, que seriam os caracteres “Ô e “£”.
. . Essas strings que estão sendo erroneamente convertidas estão vindo de um arquivo “.properties” e são inseridas nuas páginas JSP usando uma custom tag <a:key>. Eu conferi e não parece haver nenhum tipo de filtro no caminho. A definição da tag está a seguir:

<tag> <name>key</name> <tag-class>net.java.mega.action.tag.KeyTag</tag-class> <body-content>empty</body-content> <attribute> <name>key</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>filter</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag>
Qualquer ideia ou suspeita é muito bem-vinda.

Abraços.

. . Logo depois de postar a dúvida eu percebi o “tag-class” na definição dessa tag custom que aponta para <“https://java.net/projects/mega/sources/svn/content/trunk/SRC/net/java/mega/action/tag/KeyTag.java”>. Olhando o fonte, claramente essa classe é a responsável pelo problema (ela mexe com locale, resourcebundle e potenialmente roda um “HTMLUtil.filter”, apesar de a definição da tag indicar que não).
. . Minha dúvida é: como eu faço pra pegar uma string de um “.properties”? Dá pra adaptar alguma coisa ou criar uma classe nova que substitua essa “tag.KeyTag”?