Статьи

Один кувшин, чтобы управлять ими всеми: Apache TomEE + Shrinkwrap == Загрузка JavaEE

tomee_BigCat_s

ВНИМАНИЕ: я не эксперт Spring Boot. Есть много вещей, которые я нахожу по-настоящему интересными и, конечно, которые могут действительно улучшить вашу повседневную работу. Более того, я не имею ничего против Spring Boot и людей, которые его разрабатывают или используют. Но я думаю, что сообщество переоценивает / переоценивает этот продукт.

Год назад я начал получать много ссылок о блогах, твитах, информации о Spring Boot. С его сайта вы можете прочитать:

Spring Boot позволяет легко создавать автономные производственные приложения Spring, которые можно «просто запустить».

И кажется, что эта вещь только что произвела революцию в мире Java.

Например, приложение Spring MVC (также RESTful) в Spring Boot выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
@Controller
@EnableAutoConfiguration
public class SampleController {
 
    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }
 
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SampleController.class, args);
    }
}

Как вы можете видеть, магия происходит внутри класса SpringApplication, который запускает встроенный Tomcat или Jetty и, используя Spring, регистрирует этот контроллер. Довольно впечатляюще, я знаю, что за несколько строк вы можете получить конечную точку, готовую к использованию.

Но мне интересно, возможно ли использовать такой же подход в мире JavaEE с такими же низкоуровневыми и легкими требованиями. И ответ абсолютно. Я только что создал действительно маленький прототип / доказательство концепции, чтобы доказать, что это возможно.

Также, пожалуйста, не поймите меня неправильно, Spring boot предлагает множество других вещей, помимо автономных приложений, таких как мониторинг, исполнительные механизмы или разрешение зависимостей артефактов. Но это всего лишь интеграция с другими технологиями, мой пример был разработан с нуля за полтора часа, поэтому не ожидайте, что загрузочная версия Spring будет готова к использованию.

Первое, что нужно выбрать, это сервер приложений, который будет использоваться, и в этом случае нет сомнений, что лучшим для этой задачи является Apache TomEE. Это сертифицированный сервер веб-профиля Java EE, который запускается 1 секунда и работает с параметрами памяти Java по умолчанию.

Поэтому я добавил зависимости в моем файле pom.xml.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<dependencies>
 
  <dependency>
    <groupId>org.apache.openejb</groupId>
    <artifactId>tomee-embedded</artifactId>
    <version>1.7.1</version>
  </dependency>
 
  <dependency>
    <groupId>org.apache.openejb</groupId>
    <artifactId>openejb-cxf-rs</artifactId>
    <version>4.7.1</version>
  </dependency>
   
  <dependency>
    <groupId>org.apache.openejb</groupId>
    <artifactId>tomee-jaxrs</artifactId>
    <version>1.7.1</version>
  </dependency>
   
  <dependency>
    <groupId>org.jboss.shrinkwrap</groupId>
    <artifactId>shrinkwrap-depchain</artifactId>
    <version>1.2.2</version>
    <type>pom</type>
  </dependency>
 
</dependencies>

В используемой встроенной версии Tomee (1.7.1) вы можете развертывать только приложения, содержащиеся в файле, вы не можете добавить, например, сервлет программно, как это делается в Tomcat. Это может измениться в ближайшем будущем встроенного API Tomee, но сейчас мы собираемся использовать ShrinkWrap для создания этих файлов развертывания программным способом.

Вот что мы хотим сделать:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
 
@Stateless
@Path("/sample")
public class SampleController {
 
    @GET
    @Produces("text/plain")
    public String sample() {
        return "Hello World";
    }
 
    public static void main(String args[]) {
        TomEEApplication.run(HelloWorldServlet.class, SampleController.class);
    }
}

Обратите внимание, что мы импортируем только классы JavaEE, и он так же сокращен, как и Spring Boot. Всего за 2 секунды приложение готово к использованию. Помните, что вы можете использовать любую функцию, предоставляемую спецификацией веб-профиля, а также JAX-RS или JMS. Так, например, вы можете использовать JPA, Bean Validation, EJB, CDI,…

А что внутри TomEEApplication? Вы будете удивлены классом только с 70 линиями:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public class TomEEApplication {
 
  private static void startAndDeploy(Archive<!--?--> archive) {
 
    Container container;
 
      try {
        Configuration configuration = new Configuration();
        String tomeeDir = Files.createTempDirectory("apache-tomee").toFile().getAbsolutePath();
        configuration.setDir(tomeeDir);
        configuration.setHttpPort(8080);
 
        container = new Container();
        container.setup(configuration);
 
        final File app = new File(Files.createTempDirectory("app").toFile().getAbsolutePath());
        app.deleteOnExit();
 
        File target = new File(app, "app.war");
        archive.as(ZipExporter.class).exportTo(target, true);
        container.start();
 
        container.deploy("app", target);
        container.await();
 
      } catch (Exception e) {
          throw new IllegalArgumentException(e);
      }
 
      registerShutdownHook(container);
 
  }
 
  private static void registerShutdownHook(final Container container) {
    Runtime.getRuntime().addShutdownHook(new Thread() {
      @Override
      public void run() {
        try {
          if(container != null) {
            container.stop();
          }
        } catch (final Exception e) {
          throw new IllegalArgumentException(e);
        }
      }
    });
  }
 
  public static void run(Class<!--?--> ... clazzes) {
    run(ShrinkWrap.create(WebArchive.class).addClasses(clazzes));
  }
 
  public static void run(WebArchive archive) {
    startAndDeploy(archive);
  }
}

Как вы можете видеть, это действительно простой фрагмент кода, и, например, конфигурация или имя приложения жестко запрограммированы, но обратите внимание, что с помощью нескольких небольших простых изменений вы можете приступить к настройке сервера, приложения и так далее.

Подводя итог, можно сказать, что Spring Boot — это круто, но с очень простыми шагами вы можете начать делать то же самое в мире JavaEE. Мы (участники Apache TomEE) собираемся начать работать над этим и расширить эту идею.

Так что не стоит недооценивать Java EE из-за Spring Boot.