3.27.2017

Gradle от простого к сложному.



Как мы знаем, в любом проекте рано или поздно нужно организовать автоматическую сборку приложения, и для этого применяют различные инструменты. В последнее время все больше хвалят Gradle, и говорят что он лучше Maven.  Я решил разобраться что из себя представляет gradle, так ли он хорош, для этого я решил создать простой проект в IntelliJ IDEA Community Edition 2016.3.2 и подключить к нему для сборки приложения gradle. И так приступим к установке, у меня windows 7. Скачайте gradle, распакуйте в папку, у меня он будет находиться  c:\gradle-3.4.1, потом перейдите в меню Пуск, Панель управления, Все элементы панели управления, Система, выберите Дополнительные параметры системы Рис 1.



Рис 1.

Появится окно, Свойство системы, нажмите на кнопку Переменные  среды Рис 2. 


Рис 2.
  
Нажмите на кнопку создать, Рис 3.



Рис 3.
  В появившимся окне введите имя переменной Gradle_home, в значение переменной путь, куда вы распаковали gradle Рис 4, добавьте путь в переменную path Рис 5.

Рис 4.

 
Рис 5.

После того как вы прописали все переменные, запустите командную строчку и введите команду gradle -v   и если у вас установлено все правильно, то вы должны увидеть такую информацию как на Рис 6.



Рис 6.

С установкой закончено переходим к  созданию проекта HelloGradle. Создайте новый  
 проект в IntelliJ IDEA, создайте класс HelloGradle.java который выводит в консоль 
приветствие "Hello Gradle":
 
package com.lopanov;



public class HelloGradle {

    public HelloGradle() {

        System.out.println("Hello Gradle");

    }



    public static void main() {

        new HelloGradle();

    }

}
 
Перейдите в каталог проекта HelloGradle, в командной строчке наберите команду gradle task init,
 которая добавит все необходимые файлы  Gradle, точнее подключит Gradle к нашему проекту.
 При этом gradle  выполняет две свои внутренние задачи (tasks): wrapper и init, я пометил эти задачи
 единичкой на Рис 7,  двойкой я пометил справочную информацию, которую выдает gradle  по этим задачам,
 точнее  там поясняется, что они делают.  
 
                              Рис 7.
 
 Найдите файл build.gradle – это основной файл в котором вы 
должны описать задачи по сборке проекта, они выполняются последовательно  на первое время вам 
достаточно знать только это.  И так нам нужно в файл  build.gradle  добавить задачи, которые будут собирать 
наш java проект. Я спешу вас успокоить, что все  задачи вам не придется писать ручками, их уже сделали 
до нас, и поместили в так называемый  plugin. И так  вам нужно добавить в  файл build.gradle, строчку 
 apply plugin: 'java'. Попытаемся собрать наш проект, для начало выясним как это 
сделать, запросим справку какую задачу нам запустить для сборки проекта. Для этого в 
консоли выполните команду gradle tasks –all, она  покажет все задачи которые вы 
можете выполнить, они собраны по категориям, прочитав по описаниям, можно понять что нам нужна задача сборки проекта build:
 
gradle tasks –all
 
:tasks
 
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
 
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles test classes.
 
Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]
 
Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.
 
Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'HelloGradle'.
components - Displays the components produced by root project 'HelloGradle'. [incubating]
dependencies - Displays all dependencies declared in root project 'HelloGradle'.
dependencyInsight - Displays the insight into a specific dependency in root project 'HelloGradle'.
dependentComponents - Displays the dependent components of components in root project 'HelloGradle'. [incubating]
help - Displays a help message.
model - Displays the configuration model of root project 'HelloGradle'. [incubating]
projects - Displays the sub-projects of root project 'HelloGradle'.
properties - Displays the properties of root project 'HelloGradle'.
tasks - Displays the tasks runnable from root project 'HelloGradle'.
 
Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.
 
Other tasks
-----------
compileJava - Compiles main Java source.
compileTestJava - Compiles test Java source.
processResources - Processes main resources.
processTestResources - Processes test resources.
 
Rules
-----
Pattern: clean<TaskName>: Cleans the output files of a task.
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
 
BUILD SUCCESSFUL
 
Total time: 0.862 secs
 
И так выполним в консоли команду gradle build,  у нас появиться новый каталог 
 build\libs\  с файлом сборки HelloGradle.jar, заглянем в него, упс он пустой. 
Давайте залезем в документацию по plugin java, прочитаем что там говорится, что по 
умолчанию весь java  код должен храниться в директории src/main/java 
У нас он находится в папке src, читаем дальше мы можем изменить путь по умолчанию переопределив свойства sourceSets, для этого добавим в файл  build.gradle, такие строчки, пометил их желтым цветом:

// Apply the java plugin to add support for Java

apply plugin: 'java'



sourceSets {

    main {

        java {

            srcDirs = ['src']

        }

    }

}

 Пере соберем проект, почистим все командой gradle clean, потом запустите gradle build теперь все в порядке.  Подведем итоги, проекты собираются посредством выполнения последовательности задач (tasks) gradle. При помощи плагинов мы добавляем шаблонные задачи в наш проект, после чего все задачи могут гибко конфигурироваться и дорабатываться под конкретную ситуацию программиста.  И так можно сделать вывод, с помощью gradle можно быстрее добиться требуемого результата при сборке проекта.  
   

11.07.2016

Еще раз о java памяти и сборке мусора



Давайте начнем с простых вещей,  с типов языка java, существуют в нем  два типа данных примитивы и ссылочные типы или точнее сказать указатели на память. Для примера:

int a = 10; // примитивный тип
Person person = new Person(“Vit”); //сыллочный тип

 Особенность типов языка java  в том что в не зависимости от  JVM и платформы на которой JVM  крутится,  будь то Linux или Windows  размерность типов остается постоянной.  В зависимости от разрядности системы, указатели на память могут быть или 32-разрядными или 64-разрядными. Когда полю объекта ссылочного типа присваивается другой объект ссылочного типа, обычно копируется только ссылка на сам объект и при этом не создается новый объект. Рассмотрим наш пример:

Person person = new Person(“Vit”); //создаем ссылочный тип
Person person2 =person; // скопировали ссылку на объект Person(“Vit”); теперь на один объект ссылаются две переменные ссылочного типа person2 и person.
person2.setName(“Oleg”);//  и если мы изменим значение имени в ссылке person2 System.out.println(person.getName);// то при выводе объекта person  мы получим значение Oleg т.к. мы работаем с одним и тем же объектом

Продолжим,  любая программа на языке java по умолчанию запускается в главном потоке  (Thread), потоков  вы можете запустить столько, сколько вам нужно.  Поток работает с двумя видами памяти JVM: Стек и Куча.  Куча – это разделяемая или общая память где создаются объекты на которые указывают ссылочные переменные.  Стек – это место где создаются локальные переменные. Локальные переменные-примитивы  хранят свое значение  прямо в стеке, а локальные переменные-ссылочного типа будут хранить в стеке только  указатель на объект в Куче.  Любой поток имеет свой собственный стек, а куча одна для всех потоков смотрите рисунок.



Сделаем небольшое отступление, из предыдущего раздела можно сделать вывод, что ко всем ссылочным типам обязательно нужно применять синхронизацию доступа к объекту в Куче, т.е. если   доступ к одному и тому же объекту в Куче имеют разные потоки. Это правило не относится к локальным ссылочным объектам, т. к. область видимости локальных объектов в куче ограничивается только одним потоком, и по этому они не могут быть видны в другом потоке. В языке java  Кучей называется  Java Heap.  И так Java Heap – это память jvm  выделяемая во время запуска, где хранятся и живут все создаваемые нами объекты, все нелокальные переменные, массивы и т. д. Обрабатывается он, специальным менеджером памяти автоматически, который называют garbage collector (GC) - сборщиком мусора. Вы можете попросить GC только выделить память, когда вы создаете объект   ключевым словом  new,  а  сборку мусора - освобождение памяти он делает автоматически. Хотя есть два метода  System.gc() и Runtime.gc() которые, просят “GC  запуститься”, но на них нельзя полагаться, поскольку другие более приоритетные потоки могут отложить их выполнение.  JVM  поставляется с несколькими типами GC, которые можно выбрать и настроить под свои нужды посредством параметров  которые передаются при запуске jvm. Бывают случаи когда не хватает памяти процессу JVM,  тогда  возникает ошибка java.lang.OutOfMemoryError, об этой ошибке можно подробней почитать здесь, так же я вам советую прочитать статью о виртуальной машине Java,   хотя информация в них уже немного устарела. А устарела она в том, что  с 8 версии jvm, PermSize уже не используется и его заменили областью памяти которая называется class metadata. До 8 версии jvm, PermSize была составной частью Java Heap.  И как сказано в статьях, там хранятся все метаданные загруженные  ClassLoader’ом , еще эту память называют  словом  Method Area. Пожалуйста ознакомтесь с моей статьей о памяти которой обладает процесс jvm.  Я думаю с вас достаточно пока этой информации. У меня есть планы написать  в следующих статьях о разных типах GC и их настройке. А на сегодня я думаю вам хватит этой информации которую я вам дал по ссылкам, не спеша переварите её.