import org.apache.tomee.bootstrap.Server;
public class Main {
public static void main(String[] args) {
final Server server = Server.builder().build();
System.out.println("Listening for requests at " + server.getURI());
}
}
Serverless Builder API
A API Server.Builder
permite que você construa uma instância embutida(embedded) ou sem servidor(serverless) de Tomcat/TomEE dentro da sua JVM, efetivamente executando Tomcat/TomEE como uma biblioteca simples.
O design da API pode ser melhor descrito como uma API de construtor funcional (FBA) e permite efetivamente fornecer funções e referências de método que realmente auxiliam no processo de construção do servidor. É por meio dessas funções que você pode implantar aplicativos, modificar configurações e executar com eficácia qualquer código de que você precisa para ajudar a preparar a instância do servidor.
Uma visão geral de alto nível dos métodos builder disponíveis após chamar Server.builder ()
são os seguintes:
public static class Builder
public Builder httpPort(final int port)
public Builder ajpPort(final int port)
public Builder add(final String name, final byte[] bytes)
public Builder add(final String name, final Supplier<byte[]> content)
public Builder add(final String name, final String content)
public Builder add(final String name, final File content)
public Builder add(final String name, final Archive contents)
public Builder home(final Consumer<File> customization)
public Builder and(final Consumer<Builder> consumer)
public Server build()
Para realmente saber como usar a API, primeiramente devemos entender os conceitos catalina.home
e catalina.base
do Tomcat e o que realmente acontece quando chamamos Server.builder().Build()
.
Compreendendo a home e base do Tomcat
É um fato pouco conhecido que por décadas o Tomcat teve a capacidade de executar várias instâncias a partir de um único zip do Tomcat. O Tomcat usa uma variável catalina.home
para identificar a localização do zip extraído onde as bibliotecas do servidor podem ser encontradas e um catalina.base
por instância para definir a localização dos arquivos de configuração, arquivos de log e aplicativos da web dessa instância.
Em nossa situação, seu classpath JVM é efetivamente o catalina.home
e quando usamos a API do Server
estamos criando um catalina.base
muito fino que contém os arquivos de configuração, arquivos de log e webapps para essa instância de servidor construído (Tomcat). Se você usar a API Server
dez vezes na mesma JVM, terá 10 diretórios ` catalina.base`. No entanto, eles são considerados locais de trabalho temporários e serão excluídos na saída da JVM.
Chamando o Server.builder().build()
Quando o método build()
do Server.Builder
é chamado, as seguintes ações são realizadas nesta ordem:
-
Quaisquer funções adicionadas via
and(final Consumer<Builder> consumer)
são executadas. Isso permite que seja fornecida uma função que modifique ainda mais o construtor antes de qualquer construção ser executada. Várias modificações do construtor podem ser agrupadas em uma função que as instala todas. -
É criado um diretório temporário que servirá como
catalina.home
ecatalina.base
e as configurações padrão comoserver.xml
,logging.properties
etomee.xml
são copiadas. -
AQuaisquer funções adicionadas por meio de
add(final String destinationPath, final Supplier<byte[]> content)
são executadas e quaisquer bytes fornecidos, Strings ou Arquivos são gravados emdestinationPath
dentro do diretório temporário. Isso permite que as configurações padrão comoserver.xml
sejam sobrescritas ou aplicativos sejam escritos no diretóriowebapps/
. -
As portas são definidas modificando-se
conf/server.xml
. SehttpPort
não foi definido, as portas serão aleatórias. -
Todas as funções adicionadas via
home(final Consumer<File> customization)
são executadas. O diretório temporário será fornecido como o valor deFile
. -
A instância Tomcat/TomEE é iniciada e retornada como uma instância de
Server
.
Vendo o resultado de Server.builder().Build()
Ajuda muito poder ver o que foi construído. Podemos fazer isso instalando uma referência de função ou método como mostrada abaixo.
import org.apache.tomee.bootstrap.Server;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Server.builder()
.home(Main::list)
.build();
}
private static void list(final File home) {
try {
Files.walk(home.toPath())
.sorted()
.forEach(System.out::println);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
Quando o executamos, devemos ver uma saída semelhante a esta:
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/catalina.policy
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/catalina.properties
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/context.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/jaspic-providers.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/jaspic-providers.xsd
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/logging.properties
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/server.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/system.properties
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/tomcat-users.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/tomcat-users.xsd
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/tomee.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/web.xml
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/logs
/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/webapps
O acima representa o que sai da caixa ao chamar Server.builder().Build()
sem modificações.
Criação de aplicativos com Archive
A segunda classe a aprender é Archive
e é essencialmente um construtor de aplicativos simples. Com essa abordagem, todas as suas classes já estão efetivamente no classpath e visíveis, portanto, em última análise, as únicas classes que precisam ser incluídas são Servlets anotados, EJBs, CDI Beans, classes JAX-RS, etc.
public class Archive
public static Archive archive()
public Archive manifest(final String key, final Object value)
public Archive manifest(final String key, final Class value)
public Archive add(final String name, final byte[] bytes)
public Archive add(final String name, final Supplier<byte[]> content)
public Archive add(final String name, final String content)
public Archive add(final String name, final File content)
public Archive add(final String name, final Archive archive)
public Archive add(final String name, final URL content)
public Archive add(final Class<?> clazz)
public Archive addDir(final File dir)
public Archive addJar(final File file)
public File toJar()
public File toJar(final File file)
public File toDir()
public void toDir(final File dir)
Você pode usar APIs como ShrinkWrap para construir os jars e arquivos war como uma alternativa para Archive . Qualquer coisa que possa produzir um arquivo jar, um arquivo war ou uma estrutura de diretório war explodida (descompactada) funcionará.
|
Creating a ROOT war
Neste exemplo, estamos efetivamente adicionando três classes a um Archive
que é adicionado a um novo diretório webapps/ROOT/WEB-INF/classes
.
import org.apache.tomee.bootstrap.Archive;
import org.apache.tomee.bootstrap.Server;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
public class Main {
public static void main(String[] args) {
final Server server = Server.builder()
.add("webapps/ROOT/WEB-INF/classes", Archive.archive()
.add(Api.class)
.add(Movie.class)
.add(MovieService.class))
.home(Main::list)
.build();
System.out.println("Listening for requests at " + server.getURI());
}
private static void list(final File home) {
try {
Files.walk(home.toPath())
.map(Path::toFile)
.filter(File::isFile)
.map(File::getAbsolutePath)
.map(s -> "..." + s.substring(49))
.sorted()
.forEach(System.out::println);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
Quando isso for executado, veremos o método Main.list
, que é executado logo antes do início do servidor, imprimirá o seguinte:
...temp710654453954858189dir/apache-tomee/conf/catalina.policy
...temp710654453954858189dir/apache-tomee/conf/catalina.properties
...temp710654453954858189dir/apache-tomee/conf/context.xml
...temp710654453954858189dir/apache-tomee/conf/jaspic-providers.xml
...temp710654453954858189dir/apache-tomee/conf/jaspic-providers.xsd
...temp710654453954858189dir/apache-tomee/conf/logging.properties
...temp710654453954858189dir/apache-tomee/conf/server.xml
...temp710654453954858189dir/apache-tomee/conf/system.properties
...temp710654453954858189dir/apache-tomee/conf/tomcat-users.xml
...temp710654453954858189dir/apache-tomee/conf/tomcat-users.xsd
...temp710654453954858189dir/apache-tomee/conf/tomee.xml
...temp710654453954858189dir/apache-tomee/conf/web.xml
...temp710654453954858189dir/apache-tomee/webapps/ROOT/WEB-INF/classes/org/superbiz/movie/Api.class
...temp710654453954858189dir/apache-tomee/webapps/ROOT/WEB-INF/classes/org/superbiz/movie/Movie.class
...temp710654453954858189dir/apache-tomee/webapps/ROOT/WEB-INF/classes/org/superbiz/movie/MovieService.class