Добавляем низкоуровнивые библиотеки (*.so или *.dll)

Если либа (*.jar) для работы требует *.so или *.dll, то выручает такой прием:

  1. В корне проект делаем папку libs. (Для сервера, например wildfly, создаем в /configuration)
  2. А дальше, перед вызовом библиотечного класса, кастуем магию:

String path = System.getProperty("user.dir") + /libs";
String currentLibPath = System.getProperty("java.library.path");
System.setProperty("java.library.path", currentLibPath + File.Separator + path);

Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);

Всё это оборачиваем в try catch.
Для сервера, например, wildfly указываем вот так:

String path = System.getProperty(Constants.JBOSS_SERVER_CONFIG_DIR) + File.separator + "/libs";

Apache http client для запросов с сертификатом

Казалось бы, такая тривиальная задача, есть сертификат в контейнере p12, пароль от него, и URL через https. Но чтобы это взлетело повозиться всё же приходится:

private CloseableHttpClient buildSSLClient()
           throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {

  KeyStore keyStore = KeyStore.getInstance("PKCS12");
  try (InputStream in = Files.newInputStream(Paths.get(certPath))) {
      keyStore.load(in, certPass.toCharArray());
  }

  SSLContextBuilder sslContextBuilder = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true);
  sslContextBuilder.loadKeyMaterial(keyStore, certPass.toCharArray());

  SSLContext context = sslContextBuilder.build();
  SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(context, null, null, NoopHostnameVerifier.INSTANCE);

  final HttpClientBuilder builder = HttpClients.custom();

  final RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(TIMEOUT)
                .setConnectTimeout(TIMEOUT)
                .setSocketTimeout(TIMEOUT)
                .build();

  Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("https", socketFactory).build();

  builder.setDefaultRequestConfig(requestConfig);
  builder.setConnectionManager(new BasicHttpClientConnectionManager(registry));

  return builder.build();
}

Где
certPath – путь до серта *.p12
certPass
– пароль от контейнера

Интеграционное тестирование с maven. Часть 1. Запускаем wildfly во время сборки

Не будем углубляться далеко в теорию, так как по определению интеграционного тестирования пруд пруди различных статей. Вкратце, интеграционное тестирование (в дальнейшем будем сокращать до ИТ) поможет протестировать некоторый процесс нашего приложения. Например, если наше приложение проводит какие-нибудь платежи, то ИТ помогут выполнить платеж с разными данными и проверить что на выходе мы получили то, что ожидали. То есть в БД будут лежать ожидаемые данные, результатом операции будет успешный платеж и т.д. Цель таких тестов – не прогон отдельных методов или цепочки методов как при юнит тестировании, а тестирование общей логики приложения, убеждение что приложение делает то, что от него ожидают и не делает того, чего от него не ожидают.

Прежде, чем двигаться дальше, необходимо понимать общие принципы сборки проектов maven. Как минимум, необходимо знать что maven разбивает сборку на фазы. Если посмотреть на полный список фаз, то можно увидеть вот эти 3 штуки почти в самом конце сборки: pre-integration-test, integration-test и post-integration-test. Это как раз то что нам нужно. Также необходимо знать о профилях и понимать как работать с плагинами, нужно знать что у плагинов бывают цели (goals) и что эти цели можно вызывать, завязывая их на определенные стадии сборки.

Для проведения ИТ мы будем полностью поднимать окружение прямо во время сборки, то есть во время фаз ИТ, указанных выше. Нам необходимо поднять сервер, настроить его, развернуть тестовую БД, задеплоить в него необходимые модули и собственно провести тесты. То есть, с нуля поднять все, что нужно для работы приложения, как бы “с чистого листа”, чтобы быть уверенными, что на тесты не влияет окружение. В этой статье займемся стартом сервера и разворачиванием приложения во время сборки. Возьмем пример из моей первой статьи, и начнем его модифицировать.

Продолжить чтение

Простой модульный web проект с maven. Часть 2. DataSource и JPA: добавляем postgres и hibernate

Следующим шагом добавим к нашему проекту поддержку БД. Подключение будем осуществлять через DataSource. Это поможет нам не беспокоится о подключении к БД во время разработки от слова совсем.

Первым делом скачаем postgres. Так же нам облегчит жизнь PgAdmin (если вы качали пакет для Windows то он по умолчанию ставится за компанию, для Linux ставим отдельно). PgAdmin при входе спросит пароль для суперпользователя postgres. Как только подключение наладится вы, скорее всего, увидите тестовую БД postgres. Добавляем новую БД (я назвал ее demo). При добавлении достаточно указать имя и владельца (postgres), остальное в нашем примере роли не играет. Все эти махинации, конечно, можно провернуть и без всяких pgAdmin, а просто в консоли, но пойдем простым путем.

Теперь создадим DataSource. Это делается проще чем кажется. Первым делом необходимо прокинуть jdbc драйвер в Wildfly. Один из способов  – просто задеплоить jar драйвера, а второй – добавить драйвер как модуль WildFly. Пойдем более надежным – вторым способом (первый пригодится нам в следующих частях).

Продолжить чтение

Простой модульный web проект с maven. Часть 1

 

Трудно описать всю пользу использования maven при разработке и сборке web-приложений на Java. В данной статье я кратко опишу шаги для создания очень простого приложения, используя несколько maven модулей. Разбитие приложения на модули, в некоторых случаях, будет очень полезным архитектурным решением. С разбиением на модули, приложение получает больше гибкости, так как связь между модулями как правило довольно слабая (например через общую БД или посредством HTTP запросов), что делает модули, в каком-то смысле, независимыми друг от друга (например, к вашему приложению необходимо добавить панель администратора, уместно будет вынести ее в отдельный модуль, а связь с основным приложением реализовать через БД).

Также удобно с помощью модулей отстраивать иерархию приложения. Например, EJB приложения, реализующие бизнес логику, вынести в отдельный модуль, который будет собираться в jar, само web-приложение, реализующее логику взаимодействия и включая, например, сервлеты вынести в другой, который будет собираться в war. Оба эти модуля можно включить в третий модуль, который уже соберется в ear, и будет представлять все приложение целиком (на практике же, я чаще встречал объединение ejb и сервлетов в одном модуле).

Итак, создадим простое приложение, включающее модуль под web-приложение и модуль для сборки ear. Само приложение будет состоять из одинокого ejb, отвечающим на пару запросов.

Продолжить чтение