O plug -in fornece recursos de implantação de aplicativos da Web para um contêiner da Web incorporado Tomcat em qualquer construção Gradle. Estende o plugin de guerra. No momento, as versões Tomcat 6.0.x, 7.0.x, 8.0.x, 8.5.x e 9.0.x são suportadas.
O caso de uso típico deste plug -in é apoiar a implantação durante o desenvolvimento. O plug -in permite o desenvolvimento rápido de aplicativos da Web devido aos tempos de inicialização rápida do contêiner. Gradle inicia o recipiente incorporado na mesma JVM. Atualmente, o contêiner não pode ser bifurcado como um processo separado. Este plug -in também não pode implantar um arquivo de guerra em um contêiner remoto. Se você estiver procurando por esse recurso, dê uma olhada no plug -in de carga.
Para usar a funcionalidade do plug -in, você precisará adicionar o artefato binário ao seu script de construção e aplicar o plug -in.
O frasco do plug -in precisa ser definido no caminho de classe do seu script de construção. Está diretamente disponível no portal do plug -in gradle. O snippet de código a seguir mostra um exemplo sobre como recuperá -lo:
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath ' com.bmuschko:gradle-tomcat-plugin:2.7.0 '
}
}O arquivo JAR vem com dois plugins:
| Identificador de plug -in | Depende de | Tipo | Descrição |
|---|---|---|---|
| com.bmuschko.tomcat-Base | - | Tomcatbaseplugin | Fornece tipos de tarefas personalizados do Tomcat, pré-configuras ClassPath. |
| com.bmuschko.tomcat | com.bmuschko.tomcat-Base | Tomcatplugin | Fornece tarefas para iniciar e interromper um contêiner incorporado e expõe a extensão chamada tomcat . |
O plugin com.bmuschko.tomcat ajuda a começar rapidamente. Se você estiver bem se as tarefas pré -configuradas, esta é a opção preferível. A maioria dos usuários de plug -in optará com esta opção. Para usar o plug -in Tomcat, inclua o seguinte snippet de código em seu script de construção:
apply plugin: 'com.bmuschko.tomcat'
Se você precisar de controle total sobre suas tarefas ou não quiser ir com as tarefas pré-configuradas, convém usar o plug-in com.bmuschko.tomcat-base . Pode ser o caso se você deseja configurar o contêiner apenas para testes funcionais. A desvantagem é que cada tarefa deve ser configurada individualmente em seu script de construção. Para usar o plug -in Base Tomcat, inclua o seguinte snippet de código em seu script de construção:
apply plugin: 'com.bmuschko.tomcat-base'
Além disso, as bibliotecas de tempo de execução do Tomcat precisam ser adicionadas ao tomcat de configuração. No momento, as versões Tomcat 6.0.x, 7.0.x, 8.0.x, 8.5.x e 9.0.x são suportadas pelo plug -in. Certifique -se de não misturar bibliotecas do Tomcat de diferentes versões.
Tomcat 6.0.x:
repositories {
mavenCentral()
}
dependencies {
def tomcatVersion = ' 6.0.51 '
tomcat " org.apache.tomcat:catalina: ${ tomcatVersion } " ,
" org.apache.tomcat:coyote: ${ tomcatVersion } " ,
" org.apache.tomcat:jasper: ${ tomcatVersion } "
}Tomcat 7.0.x:
repositories {
mavenCentral()
}
dependencies {
def tomcatVersion = ' 7.0.76 '
tomcat " org.apache.tomcat.embed:tomcat-embed-core: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-logging-juli: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-jasper: ${ tomcatVersion } "
}Tomcat 8.0.x:
repositories {
mavenCentral()
}
dependencies {
def tomcatVersion = ' 8.0.42 '
tomcat " org.apache.tomcat.embed:tomcat-embed-core: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-logging-juli: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-jasper: ${ tomcatVersion } "
}Tomcat 8.5.x:
Esteja ciente de que a dependência tomcat-embed-logging-juli é necessária apenas para ativar o log de contêineres via log4j 1.x (que não é mais suporte da comunidade LOG4J). Log4J 2.x pode ser usado para o registro de contêineres sem declarar bibliotecas extras.
repositories {
mavenCentral()
}
dependencies {
def tomcatVersion = ' 8.5.16 '
tomcat " org.apache.tomcat.embed:tomcat-embed-core: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-logging-juli:8.5.2 " ,
" org.apache.tomcat.embed:tomcat-embed-jasper: ${ tomcatVersion } "
}
tomcat {
httpProtocol = ' org.apache.coyote.http11.Http11Nio2Protocol '
ajpProtocol = ' org.apache.coyote.ajp.AjpNio2Protocol '
}Tomcat 9.0.x:
Esteja ciente de que a dependência tomcat-embed-logging-juli é necessária apenas para ativar o log de contêineres via log4j 1.x (que não é mais suporte da comunidade LOG4J). Log4J 2.x pode ser usado para o registro de contêineres sem declarar bibliotecas extras.
repositories {
mavenCentral()
}
dependencies {
def tomcatVersion = ' 9.0.1 '
tomcat " org.apache.tomcat.embed:tomcat-embed-core: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-logging-juli:9.0.0.M6 " ,
" org.apache.tomcat.embed:tomcat-embed-jasper: ${ tomcatVersion } "
}
tomcat {
httpProtocol = ' org.apache.coyote.http11.Http11Nio2Protocol '
ajpProtocol = ' org.apache.coyote.ajp.AjpNio2Protocol '
} O plug-in com.bmuschko.tomcat predefina as seguintes tarefas prontas para uso:
| Nome da tarefa | Depende de | Tipo | Descrição |
|---|---|---|---|
| Tomcatrun | - | Tomcatrun | Inicia uma instância do Tomcat e implanta o aplicativo da Web explodido para ele. |
| Tomcatrunwar | - | Tomcatrunwar | Inicia uma instância do Tomcat e implanta a guerra. |
| Tomcatstop | - | Tomcatstop | Pare a instância do Tomcat. |
| Tomcatjasper | - | Tomcatjasper | Executa o compilador JSP e transforma as páginas JSP na fonte Java usando o Jasper. |
O plug -in Tomcat usa o mesmo layout que o plug -in de guerra.
O plug -in Tomcat expõe as seguintes propriedades através da extensão chamada tomcat :
httpPort : a porta TCP que o tomcat deve ouvir para solicitações HTTP em (padrão para 8080 ).httpsPort : A porta TCP que o tomcat deve ouvir para solicitações HTTPS em (Padrões para 8443 ).ajpPort : A porta TCP que o Tomcat deve ouvir para solicitações de AJP em (Padrões para 8009 ).stopPort : a porta TCP que o tomcat deve ouvir para solicitações de administrador em (padrão para 8081 ).stopKey : a chave a passar para o tomcat ao solicitar que ele pare (padrão para null ).contextPath : o caminho do contexto da URL sob o qual o aplicativo da Web será registrado (padrões para o nome da guerra).enableSSL : determina se o conector HTTPS deve ser criado (padrão para false ).daemon : Especifica se o servidor Tomcat deve ser executado em segundo plano. Quando é verdade, essa tarefa é concluída assim que o servidor iniciar. Quando falsa, essa tarefa bloqueia até que o servidor Tomcat seja interrompido (padrão para false ).keystoreFile : o arquivo keystore a ser usado para SSL, se ativado (por padrão, uma parte do keystore será gerada).httpProtocol : o nome da classe HTTP Protocol Handler a ser usado (padrão para org.apache.coyote.http11.Http11Protocol ).httpsProtocol : O nome da classe HTTPS Protocol Handler a ser usado (Padrões para org.apache.coyote.http11.Http11Protocol ).ajpProtocol : o nome da classe Handler do protocolo AJP a ser usado (padrão para org.apache.coyote.ajp.AjpProtocol ).users : Lista de usuários com username , password e roles . Usado para configurar o Tomcat com a autenticação básica com esses usuários. O código de exemplo a seguir mostra como alterar as portas HTTP/HTTPS padrão. Para ativar o SSL, definimos a propriedade enableSSL como true . O aplicativo da Web estará acessível no sample-app Caminho de Contexto.
tomcat {
httpPort = 8090
httpsPort = 8091
enableSSL = true
contextPath = ' sample-app '
users {
user {
username = ' user1 '
password = ' 123456 '
roles = [ ' developers ' , ' admin ' ]
}
user {
username = ' user2 '
password = ' abcdef '
roles = [ ' manager ' ]
}
}
}Além disso, você pode definir as seguintes propriedades opcionais da tarefa:
contextPath : o caminho do contexto da URL que seu aplicativo da Web será registrado (Padrões para o nome da guerra).webDefaultXml : o web.xml padrão. Se não for definido, uma instância de org.apache.catalina.servlets.DefaultServlet e org.apache.jasper.servlet.JspServlet será configurada.additionalRuntimeResources : define frascos ou diretórios de tempo de execução adicionais que não são fornecidos pelo aplicativo da web.URIEncoding : Especifica a codificação de caracteres usada para decodificar os bytes URI pelo conector HTTP (padrão para UTF-8 ).daemon : Especifica se o servidor Tomcat deve ser executado em segundo plano. Quando é verdade, essa tarefa é concluída assim que o servidor iniciar. Quando falsa, essa tarefa bloqueia até que o servidor Tomcat seja interrompido (padrão para false ).configFile : o caminho para o arquivo XML do contexto do tomcat (padrão para src/main/webapp/META-INF/context.xml para tomcatRun , padrão para META-INF/context.xml dentro da guerra por tomcatRunWar ).outputFile : O arquivo para gravar mensagens de log do tomcat para. Se o arquivo já existir, novas mensagens serão anexadas.reloadable : Força a varredura de contexto se você não usar um arquivo de contexto (padrão para true ).keystorePass : a senha do keystore a ser usada para SSL, se ativado.truststoreFile : o arquivo Truststore a ser usado para SSL, se ativado.truststorePass : a senha do TrustStore a ser usada para SSL, se ativada.clientAuth : a configuração do cliente a ser usada, os valores podem ser: true , false ou want (padrão para false ). Nota: keystoreFile e truststoreFile requerem uma instância de um arquivo File , por exemplo file("/path/my.file")
No código de exemplo a seguir, declaramos um arquivo de contexto personalizado para a tarefa tomcatRun .
tomcatRun . configFile = file( ' context.xml ' ) Para configurar a tarefa Jasper Compiler, você pode optar por definir as seguintes propriedades dentro do fechamento jasper da extensão do tomcat :
validateXml : determina se web.xml deve ser validado (padrão para null ).validateTld : determina se web.xml deve ser validado (padrão para null ).uriroot : o diretório raiz do aplicativo da web (padrão para src/main/webapp ).webXmlFragment : o arquivo de fragmento XML da Web gerado a ser referenciado pelo seu arquivo web.xml .addWebXmlMappings : Adicione automaticamente o fragmento XML da Web gerado ao arquivo web.xml . CUIDADO: Isso modificará o arquivo web.xml no projeto, não o diretório de compilação.outputDir : O diretório de saída Os JSPs compilados acabarão em (Padrões para build/jasper ).classdebuginfo : o arquivo de classe deve ser compilado com informações de depuração (padrão para true ).compiler : Qual Compilador Ant deve usar para compilar páginas JSP. Veja a documentação da ANT para obter mais informações. Se o valor não estiver definido, será usado o compilador JDT Java JDT JDT padrão em vez de usar a ANT. Nenhum valor padrão.compilerSourceVM : qual versão JDK são os arquivos de origem compatíveis com (padrão para 1.6 ).compilerTargetVM : qual versão JDK são os arquivos gerados compatíveis com (padrão para 1.6 ).poolingEnabled : determina se o pool de manipuladores de tags está ativado. Esta é uma opção de compilação. Não alterará o comportamento dos JSPs que já foram compilados (padrão para true ).errorOnUseBeanInvalidClassAttribute : Jasper deve emitir um erro quando o valor do atributo de classe em uma ação de uso não for uma classe de feijão válida (padrão para true ).genStringAsCharArray : As seqüências de texto devem ser geradas como matrizes de char, para melhorar o desempenho em alguns casos (padrão para false ).ieClassId : o valor da classe-ID a ser enviado ao Internet Explorer ao usar <jsp:plugin> tags (padrão para clsid:8AD9C840-044E-11D1-B3E9-00805F499D93 ).javaEncoding : codificação de arquivos java a ser usada para gerar arquivos de origem Java (padrões para UTF8 ).trimSpaces : os espaços brancos devem ser aparados os espaços brancos no texto do modelo entre ações ou diretrizes (padrões para TrimSpaces.TRUE ).xpoweredBy : determina se o cabeçalho de resposta X-PODERED-BY é adicionado pelo servlet gerado (padrão para false ).tomcat {
jasper {
validateXml = true
webXmlFragment = file( " $w ebAppDir /WEB-INF/generated_web.xml " )
outputDir = file( " $w ebAppDir /WEB-INF/src " )
}
}Eu recebo uma exceção de compilação ao chamar um JSP. Há algo que estou perdendo?
A exceção que você pode ver é provavelmente semelhante a esta: org.apache.jasper.JasperException: Unable to compile class for JSP . Tomcat 7.x e 8.x exige que você tenha o Eclipse J.6.x no seu caminho de classe. No entanto, esta versão da dependência não existe no Maven Central. Você terá que baixar essa dependência e colocá -la em seu próprio repositório ou definir um repositório em seu disco local, onde você pode lançá -lo. Aqui está um exemplo:
repositories {
flatDir name : ' localRepository ' , dirs : ' lib '
} Por que recebo um java.lang.ClassCastException em javax.servlet.Servlet ?
O Tomcat é muito sensível a ter várias versões das dependências javax.servlet:servlet-api e javax.servlet:jsp-api em seu caminho de classe. Por padrão, eles já são atraídos como dependências transitivas das bibliotecas Tomcat incorporadas. A exceção que você pode ver parece parecida com este:
java.lang.ClassCastException: org.springframework.web.servlet.DispatcherServlet cannot be cast to javax.servlet.Servlet
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1062)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1010)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4935)
at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5262)
at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5257)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Para corrigir isso, certifique -se de definir suas dependências de JSP e Módulo de Servlet com o escopo providedCompile como este:
providedCompile ' javax.servlet:servlet-api:2.5 ' ,
' javax.servlet:jsp-api:2.0 'Como faço para depurar remoto meu tomcat iniciado pelo plug -in?
Se você deseja depurar remotamente seu aplicativo, precisará definir as seguintes opções de JVM em sua variável de ambiente GRADLE_OPTS antes de iniciar o contêiner. O número da porta que você escolher depende de você.
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
O Tomcat ouvirá a porta especificada para as conexões de depuração remota de entrada. Ao iniciar o contêiner, você deve ver a seguinte mensagem:
Listening for transport dt_socket at address: 5005
Verifique sua documentação do IDE sobre como configurar a conexão com a porta de depuração remota.
Meu contêiner Tomcat precisa usar um conjunto de dados JNDI. Como faço para configurar meu projeto?
Antes de tudo, você deve declarar a dependência do pool de conexões usando a configuração tomcat .
Tomcat 6.0.x:
def tomcatVersion = ' 6.0.35 '
tomcat " org.apache.tomcat:dbcp: ${ tomcatVersion } "Veja as coordenadas no Maven Central para obter detalhes.
Versões posteriores:
def tomcatVersion = ' 9.0.8 '
tomcat " org.apache.tomcat:tomcat-dbcp: ${ tomcatVersion } "Veja as coordenadas no Maven Central para obter detalhes.
Se você decidir ir com as configurações padrão, coloque seu context.xml no diretório src/main/webapp/META-INF . Para definir um local personalizado, você pode usar o Convention Property configFile . Aqui está um exemplo de como defini -lo para as tarefas tomcatRun e tomcatRunWar .
[tomcatRun, tomcatRunWar] * . configFile = file( ' context.xml ' )Consulte a documentação do Tomcat para obter uma lista de atributos de contexto. O exemplo a seguir mostra como configurar um MySQL JNDI DataSource.
<? xml version = " 1.0 " encoding = " UTF-8 " ?>
< Context >
< Resource name = " jdbc/mydatabase "
auth = " Container "
type = " javax.sql.DataSource "
username = " superuser "
password = " secretpasswd "
driverClassName = " com.mysql.jdbc.Driver "
url = " jdbc:mysql://localhost:3306/mydb "
validationQuery = " select 1 "
maxActive = " 10 "
maxIdle = " 4 " />
</ Context >Como uso a implantação de código quente com o plug -in?
O plug-in fornece suporte para fora da caixa para trocar o código de bytes por meio da propriedade reloadable . Por padrão, esta opção é elaborada para que você não precise de nenhuma alteração adicional de configuração. Tudo o que você precisa fazer é ter uma instância em execução do contêiner iniciado pelo tomcatRun . Inicie seu editor favorito, altere um arquivo de fonte de produção, salve -o e recompile suas fontes em outro terminal via gradle compileJava . Depois de alguns segundos, o contexto é recarregado e você verá o comportamento refletido na janela do terminal executando o contêiner:
Reloading Context with name [/myapp] has started
Reloading Context with name [/myapp] is completed
Como alternativa, você pode usar outras tecnologias de troca de código de bytes comerciais. A configuração geralmente é específica do produto. Consulte a documentação do produto sobre como configurá -lo para o seu projeto. A seção a seguir descreve como configurar o Gradle e o plug -in com Jrebel. Antes de tudo, baixe Jrebel, instale -o em sua máquina e configure a licença. Para dizer a Jrebel qual diretório para digitalizar o código de bytes alterado, você precisa criar um arquivo rebel.xml. No seu módulo da web, coloque o arquivo em build/classes/main para que possa ser carregado pelo plug -in Tomcat. Para criar a configuração do arquivo, o plug -in gradle jrebel é útil. Não é necessário usar o plug -in. Você também pode decidir criar a configuração manualmente. Lembre -se de que a gradle clean excluirá o arquivo. Para configurar o Jrebel em um cenário de projeto de vários módulos, consulte a documentação. O snippet de código a seguir mostra um exemplo de arquivo rebel.xml .
<? xml version = " 1.0 " encoding = " UTF-8 " ?>
< application xmlns : xsi = " http://www.w3.org/2001/XMLSchema-instance " xmlns = " http://www.zeroturnaround.com "
xsi : schemaLocation = " http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd " >
< classpath >
< dir name = " /Users/ben/dev/projects/mywebproject/build/classes/main " >
</ dir >
</ classpath >
< web >
< link target = " / " >
< dir name = " /Users/ben/dev/projects/mywebproject/src/main/webapp " >
</ dir >
</ link >
</ web >
</ application > Edite seu script de inicialização gradle e adicione a seguinte linha para dizer a Gradle para usar o agente Jrebel. Certifique -se de definir a variável de ambiente REBEL_HOME que aponta para o seu diretório de instalação Jrebel.
JAVA_OPTS="-javaagent:$REBEL_HOME/jrebel.jar $JAVA_OPTS"
Na inicialização do seu módulo da web usando gradle tomcatRun você deve ver informações sobre a licença Jrebel usada e os diretórios que estão sendo digitalizados para alterações. Para o nosso exemplo de arquivo rebel.xml , seria assim:
JRebel: Directory '/Users/ben/dev/projects/mywebproject/build/classes/main' will be monitored for changes.
JRebel: Directory '/Users/ben/dev/projects/mywebproject/src/main/webapp' will be monitored for changes.
Se um arquivo foi recompilado, Jrebel indica isso escrevendo -o no console como este:
JRebel: Reloading class 'de.muschko.web.controller.TestController'.
Precisam executar testes de integração em contato como parte da minha compilação. O que precisa ser feito?
Geralmente, os testes de unidade e integração são mantidos separados por convenção. Uma convenção pode ser nomear os arquivos de origem de teste de maneira diferente, por exemplo, os testes de integração sempre terminam com o sufixo IntegrationTest , os arquivos de teste de unidade terminam com Test . Ao fazer isso, você pode executá -los separadamente. Para executar os testes de integração, você desejará executar a tarefa Tomcat como Thread Daemon e desligá -lo assim que seus testes estiverem feitos. O exemplo a seguir demonstra como configurar uma tarefa gradle que fornece essa funcionalidade. Claro que essa é apenas uma maneira de fazê -lo. O exemplo a seguir requer gradle> = 1.7:
apply plugin : ' com.bmuschko.tomcat-base '
ext {
tomcatStopPort = 8081
tomcatStopKey = ' stopKey '
}
task integrationTomcatRun( type : com.bmuschko.gradle.tomcat.tasks.TomcatRun ) {
stopPort = tomcatStopPort
stopKey = tomcatStopKey
daemon = true
}
task integrationTomcatStop( type : com.bmuschko.gradle.tomcat.tasks.TomcatStop ) {
stopPort = tomcatStopPort
stopKey = tomcatStopKey
}
task integrationTest( type : Test ) {
include ' **/*IntegrationTest.* '
dependsOn integrationTomcatRun
finalizedBy integrationTomcatStop
}
test {
exclude ' **/*IntegrationTest.* '
}Como adiciono arquivos de jar ou diretórios que não fazem parte do meu código -fonte de aplicativo da web?
Todas as tarefas do tipo AbstractTomcatRun expõem uma propriedade chamada additionalRuntimeResources que é usada para misturar com o aplicativo Web Runtime ClassPath.
[tomcatRun, tomcatRunWar] . each { task ->
task . additionalRuntimeResources << file( ' /Users/bmuschko/config/props ' )
task . additionalRuntimeResources << file( ' /Users/bmuschko/ext/jars/my.jar ' )
}