Pull to refresh
47
0.1
Viktor Alenkov @Borz

Пользователь

Send message

Динамическое подключение внешних собственных модулей и плагинов в Gradle

Reading time3 min
Views6.7K

Преамбула


Есть своя «внешняя» библиотека и есть своё приложение, использующее эту библиотеку (подгружается через внешний репозитарий). Требуется внести изменение и в библиотеку и в приложение.

Казалось бы, собери библиотеку и выложи её в локальный maven-репозитарий, а потом уже собирай приложение. Но хочется, чтобы можно было поправив код в библиотеке сразу попробовать изменения в приложении и при этом сохранить раздельное хранение кода библиотеки и приложения, включая настройки IDE и прочее.

С помощью gradle и символических связей в файловой системе такое можно легко устроить.
Читать дальше →
Total votes 9: ↑9 and ↓0+9
Comments6

Возвращаем дочерний класс из родительского. Факультатив

Reading time3 min
Views22K
С какой целью это может понадобиться? Например, если хочется использовать "текучий интерфейс". Правда, если часть методов разместить в родительском классе, то для них не получится сделать полноценный «текучий интерфейс» — эти методы требуется приводить (кастовать) к дочернему.

Казалось бы, печаль да и только, но если очень хочется, то ведь можется. Поэтому, давайте слегка нарушим правило и «известим» родительский класс о его наследниках.
Читать дальше →
Total votes 18: ↑13 and ↓5+8
Comments21

Spring и @Autowired для ENUM-типов. Факультатив

Reading time4 min
Views19K
Как известно, в Spring нельзя сделать бины для перечисляемых типов без «костылей» — у этого типа «нет» конструктора.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demoEnum0' defined in file [...\DemoEnum0.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [ru.itbasis.demo.spring.enums.DemoEnum0]: No default constructor found; nested exception is java.lang.NoSuchMethodException: ru.itbasis.demo.spring.enums.DemoEnum0.<init>()

(коммит)

В данном посте я попробую обойти это ограничение.
Читать дальше →
Total votes 12: ↑9 and ↓3+6
Comments21

Тестирование через абстрактные классы в TestNG

Reading time7 min
Views9.4K

Вступление


Вы всё ещё тестируете с помощью JUnit и не обращаете внимания на TestNG? Тогда мы идём к вам.

Одним из преимуществ TestNG является возможность создания тестовых массивов данных для одного или нескольких тестов. Но мало кто использует такое преимущество от @DataProvider как пустой набор тестовых данных. В чём оно выражается?

Допустим у нас есть некий тест testData(String value) и метод datas обеспечивающий DataProvider. Если datas вернёт нам массив из 3-х элементов, то testData выполнится 3 раза. Но если datas вернёт нам пустой массив, то testData не выполнится ни разу
Картинки


Давайте попробуем воспользоваться данной особенностью.

Читать дальше →
Total votes 6: ↑6 and ↓0+6
Comments9

Дружим Git с Putty

Reading time2 min
Views51K
Disclaimer
Предварительно делал поиск по хабру с надеждой на подобный пост, смог найти только вот этот пост, в котором вся работа производятся через TortoiseGit.

Но это не наш метод. По той причине, что в этом случае все наши IDE не смогут сами сделать Push на сервер. Да и через Git Bash ничего не получится сделать на сервере.
почему мне нужно использовать Git в связке с Putty?
Так уж получилось, что я активно использую Putty с настроенными ключами для доступа к серверам. Ключей у меня не один. Git-репозитариев тоже не один.
Конечно же, можно нагенерить OpenSSH ключей для Git-а и разрулить их через ~/.ssh/config, но это получается двойная работа – поддержка ключей в Putty и отдельная поддержка для Git.



Итак, представим, что у нас девственно чистая система, в которой нет ни Putty, ни msysgit. Приступим к настройке нашего рабочего окружения.

Установка Putty


Качаем, устанавливаем, генерим и настраиваем ключ c Pagent (инструкция, ?).

Добавляем ключ на git-сервер


Копируем публичный OpenSSH ключ из Putty-ключа
Запускаем Putty key Generator
Открываем (кнопка «Load») наш PPK-ключ
Копируем весь текст из блока «Key»

Открываем страницу с SSH ключами и добавляем из буфера наш ключ
В картинках (на примере GitHub)






Создаём и сохраняем в Putty профиль «git@github.com» и проверяем, что удаётся зайти по ключу – должна открыться и сразу закрыться консоль.
В картинках





Устанавливаем и настраиваем msysgit

Дайте весь текст!
Total votes 39: ↑27 and ↓12+15
Comments23

Пишем плагин для Maven

Reading time10 min
Views21K
Есть у меня на некоторых maven-проектах профиль, с помощью которого производится копирование shared-библиотек с последующим перезапуском сервера Tomcat.
Maven profile
<profile>
	<id>deploy-deps</id>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-dependency-plugin</artifactId>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>copy-dependencies</goal>
						</goals>
						<configuration>
							<useSubDirectoryPerScope>true</useSubDirectoryPerScope>
							<excludeGroupIds>исключаем некоторые группы, попадающие в war-архив</excludeGroupIds>
						</configuration>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>exec-maven-plugin</artifactId>
				<executions>
					<execution>
						<id>05-stop-tomcat</id>
						<phase>package</phase>
						<goals>
							<goal>exec</goal>
						</goals>
						<configuration>
							<arguments>
								<argument>-ssh</argument>
								<argument>-4</argument>
								<argument>-agent</argument>
								<argument>-i</argument>
								<argument>${putty.key}</argument>
								<argument>${ssh.user}@${ssh.host}</argument>
								<argument>${tomcat.dir.root}/bin/shutdown.sh</argument>
							</arguments>
							<executable>plink</executable>
						</configuration>
					</execution>
					<execution>
						<id>10-clean-shared-jars</id>
						<phase>package</phase>
						<goals>
							<goal>exec</goal>
						</goals>
						<configuration>
							<arguments>
								<argument>-ssh</argument>
								<argument>-4</argument>
								<argument>-agent</argument>
								<argument>-i</argument>
								<argument>${putty.key}</argument>
								<argument>${ssh.user}@${ssh.host}</argument>
								<argument>rm</argument>
								<argument>-Rf</argument>
								<argument>${tomcat.dir.shared}/*.jar</argument>
							</arguments>
							<executable>plink</executable>
						</configuration>
					</execution>
					<execution>
						<id>15-upload-shared-jars</id>
						<phase>package</phase>
						<goals>
							<goal>exec</goal>
						</goals>
						<configuration>
							<arguments>
								<argument>-scp</argument>
								<argument>-4</argument>
								<argument>-agent</argument>
								<argument>-i</argument>
								<argument>${putty.key}</argument>
								<argument>${project.build.directory}/dependency/compile/*.jar</argument>
								<argument>${ssh.user}@${ssh.host}:${tomcat.lib.shared}/</argument>
							</arguments>
							<executable>pscp</executable>
						</configuration>
					</execution>
					<execution>
						<id>20-start-tomcat</id>
						<phase>package</phase>
						<goals>
							<goal>exec</goal>
						</goals>
						<configuration>
							<arguments>
								<argument>-ssh</argument>
								<argument>-4</argument>
								<argument>-agent</argument>
								<argument>-i</argument>
								<argument>"${putty.key}"</argument>
								<argument>${ssh.user}@${ssh.host}</argument>
								<argument>bin/startup.sh</argument>
							</arguments>
							<executable>plink</executable>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</profile>

отходя в сторону, поведаю для чего сей профиль
В части проектов используется связка Nginx+Tomcat. Для данной связки реализовано следующее:
  1. Для всего статичного контента используется некий каталог за пределами webapps. В этот каталог «смотрит» Nginx и отдаёт по web-пути "/static/*"
  2. Все shared java-библиотеки (редко изменяемые) грузятся в каталог ${catalina.home}/shared, и в Tomcat в файле conf/catalina.properties настроена для этого переменная «shared.loader»
  3. Для каждого инстанса Tomcat создан свой системный пользователь
  4. Для доступа по SSH используются ключи и у каждого разработчика он свой

Соответственно, загрузка статичного контента и shared-библиотек это отдельные профили. Всё остальное собирается в war-архив и устанавливается через стандартный web-manager Tomcat-а.
А чтобы не плодить конфигураций, используется PAgent, в который уже и добавленые нужные нам private keys. Они же используются для подключения через Putty

Лежит себе профиль в pom.xml, не кусается вроде бы, даже пашет потихоньку на благо программера, но вот только есть в нём пара «минусов» — занимает много места при развёрнутом pom.xml да ещё и в новые проекты приходится вставлять.
И если от второго минуса можно избавиться написав шаблон в любимая_IDE или свой архетип наваять, то от первого минуса не так-то просто избавить.

Точно ли не так просто? может «обернём» этот профиль в виде плагина для Maven? Сказано, сделано.
Читать дальше →
Total votes 16: ↑15 and ↓1+14
Comments7

Spring и обработка событий в Hibernate

Reading time3 min
Views18K
Как-то обделена на хабре такая тема, как обработка событий при работе с сущностями с использованием Hibernate — я смог найти только один пост уже почти мохнатого года. Но то аудит, а нам нужна возможность автоматизировать работу с некоторыми атрибутами сущностей и при этом упростить процедуру работы с ними.

Для начала создадим демонстрационный стенд с двумя сущностями User и AnObject, а так же DAO-слоем для них.
Код
Здесь и далее привожу только значимые куски кода — в полной версии можно посмотреть на github
@Entity
@Table(name = "user")
public class User {
        @Id
        @GeneratedValue
        private long id;
        @Basic
        @Column(name = "username", updatable = false, unique = true, nullable = false)
        private String username;

        // getter and setter
}

@Entity
@Table(name = "anObject")
public class AnObject {
        @Id
        @GeneratedValue
        private long id;
        @Column
        private String value;

        // getter and setter
}


Читать дальше →
Total votes 12: ↑11 and ↓1+10
Comments17

PowerMock(+Mockito) +TestNG и имитация вызова (mock) статических методов

Reading time5 min
Views15K
На хабре уже была статья с примерами использования PowerMock, но в ней не хватает такого описания, как имитации вызова статических методов как самостоятельных «единиц» в классе, так и в гибридном использовании, когда часть статических методов у класса подменяются «заглушкой», а часть вызываются реально. Попробую исправить эту нишу.

Для начала создадим демонстрационный класс со статическими методами (commit):

public class ClassStatic {
	static String getValue() {
		return "value";
	}

	static String getValue(final String s) {
		return getValue() + s;
	}
}

Читать дальше →
Total votes 12: ↑10 and ↓2+8
Comments4

Jelastic Cloud + Maven. Часть 1

Reading time4 min
Views4.8K
Что такое Jelastic Cloud? это облачный java-хостинг, а с некоторых пор и php-хостинг, который поддерживает такие сервера приложений как Tomcat 6/7, Jetty 6, Glassfish 3, среду выполнения Java 6/7, а так же БД MariaDB 5.5, MySQL 5.5, PostgreSQL 8.4, MongoDB 2.0 и CouchDB 1.2 (версии указаны на момент публикации поста). Более подробно можно узнать у них на сайте.

Мы же поговорим про создание и загрузку java web-приложения в cloud-окружение посредством maven-плагина от Jelastic.

В первой части мы создадим окружение в облаке и создадим простой web-проект, который и установим в окружение.
Читать дальше →
Total votes 4: ↑4 and ↓0+4
Comments8

Information

Rating
2,528-th
Location
Россия
Works in
Registered
Activity

Specialization

Backend Developer
Lead
Golang
Docker
Git
PostgreSQL
gRPC
CI/CD