В главном проекте есть подпроект 'uploader'. (точнее просто просто папка с ещё одним
gradle проектом)
Мне надо, чтобы при выполнении таска в главном проекте, выполнялся таск в подпроекте.
А именно таск run с определёнными параметрами. (такие как путь до собранной в главном
проекте jar итп)
Ответы
Ответ 1
В build.gradle корневого проекта надо добавить задачу, которая будет вызывать gradle
в подпроекте с нужными параметрами:
task runUploader(type: GradleBuild) {
buildFile = 'uploader/build.gradle'
tasks = ['run']
startParameter.projectProperties = [jarDir: "/jardir"]
}
и добавить зависимости, чтобы эта задача вызывалась в нужный момент, например так:
myTask.dependsOn runUploader
Вот такая ошибка в android studio
Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException:
org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.8.0_65\bin\java.exe''
finished with non-zero exit value 1
Вот build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.example.chingiz.diplom"
minSdkVersion 17
targetSdkVersion 23
versionCode 1
versionName "1.0"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile files('libs/google-api-services-youtube-v3-rev124-1.19.0.jar')
compile files('libs/google-api-client-1.21.0.jar')
compile files('libs/google-oauth-client-1.21.0.jar')
compile files('libs/google-http-client-1.21.0.jar')
compile files('libs/jsr305-1.3.9.jar')
compile files('libs/google-http-client-jackson2-1.21.0.jar')
compile files('libs/jackson-core-2.1.3.jar')
compile files('libs/google-api-client-android-1.21.0.jar')
compile files('libs/google-http-client-android-1.21.0.jar')
compile files('libs/picasso-2.5.2.jar')
}
Подскажите что может быть?
Ответы
Ответ 1
Это не обязательно именно ваш случай, но, глядя на количество jar-библиотек в вашем
проекте, думаю, очень вероятный сценарий. Когда какие-то из зависимостей дублируют
друг друга, при попытке компиляции появляется точь-в-точь такая же ошибка, как у вас.
Проверить, нет ли у вас дублируемых зависимостей можно открыв терминал в папке с
проектом и прописав там команду ./gradlew имяпроекта:dependencies.
Оцените визуально это дерево на предмет повторяющихся зависимостей. Если они есть
- ликвидируйте их и компилируйте заново.
В моей практике такое было, и справился с этой ошибкой именно этим путём.
P.S.
А ещё, чтобы логи при подобных ошибках были более развёрнутыми, зайдите в Settings
-> Build, Execution, Deployment -> Build Tools -> Compiler и пропишите там в поле Command-line
Options --stacktrace
При попытке запустить созданный простейший проект, когда уже выбрал виртуальное устройство,
выскакивает сообщение об ошибке - Failed to complete gradle execution
Вот пишет в Gradle Console
Build failed with an exception.
What went wrong:
Execution failed for task
':app:preDexDebug'.
com.android.ide.common.internal.LoggedErrorException:
Failed to run command:
C:...\build-tools\21.1.1\dx.bat --dex
--output C:...\build\intermediates\pre-dexed\debug\internal_impl-21.0.2-255816edbbf414e2d0b1a5ac3a093bcb291d606e.jar
C:...\build\intermediates\exploded-aar\com.android.support\support-v4\21.0.2\libs\internal_impl-21.0.2.jar
Error Code: 1 Output: Try: Run with
--stacktrace option to get the stack trace. Run with --info or --debug
option to get more log output. BUILD
FAILED
Ошибки в Gradle не подсвечивает
Ответы
Ответ 1
Возможно, ему недостаточно памяти, попробуйте в настройках File-->Setting-->Gradle--
в окне Gradle Vm Option добавить -Xmx256m.
Такая ошибка была в версии Tool 24.0.0, в новых версиях ее пофиксили.
Проблема в файле tools/lib/find_java.bat в строке 27 лишний пробел после arch_ext=32
find /i "x86" > NUL && set arch_ext=32 || set arch_ext=64. Правильный запрос выглядит
так find /i "x86" > NUL && set arch_ext=32|| set arch_ext=64.
Ответ 2
Скачайте новый build-tools (на текущий момент 21.1.2 актуален) и в build.gradle поменяйте
buildToolsVersion "21.0.2" на "21.1.2". Тут проблема не в gradle, т.к. он просто делает
сборку, используя ресурсы, а, скорее всего, в криво ставшем SDK. На всякий случай переместите
SDK в корень директории, хотя в AS, вроде, поправили проблему кодировки, но я особо
не проверял.
Ответ 3
Была такая же ошибка. При помощи системы контроля версий установил что проблема в
файле dimens.xml
Вместо
100dp
использовал
100
(разница в отсутствии dp).
Возможно кому-то поможет.
В сети много информации об этом не хитром деле, но мне все же не понятен один момент.
Есть 2 android - приложения. Для этих двух приложений существует общая библиотека.
Эта схема успешно работала в Eclipse.
Сейчас же, когда перешел на Android Studio, я пытаюсь повторить тот же фокус (разными
способами), но у меня не получается.
Я хочу сделать ссылку на указанный библиотечный проект. Чтоб все изменения сразу
отражались во всех приложениях, к которым эта библиотека подключена. А все что у меня
получается это с сделать копию библиотечного проекта. В таком случае не о какой общности
библиотеки речи не идет.
Как быть?
Ответы
Ответ 1
Android Studio для сборки проекта использует систему сборки Gradle, поэтому решается
данный вопрос через возможности именно данной системы сборки, а не непосредственно
Android Studio
Для того, чтобы подключить в свой проект другой, независимый от текущего, проект
(например, разрабатываемую вами же библиотеку) в Android Studio, необходимо в файле
settings.gradle текущего проекта добавить ссылку на другой проект:
include ':myLibrary'
project(':myLibrary').projectDir = new File('../MyProjects/myLibrary')
Здесь мы подключаем к текущему проекту проект myLibrary.
../MyProjects/myLibrary - путь до подключаемого проекта.
Ссылка на подключенный проект появится в дереве файлов Android Studio, при редактировании
вы будете вносить изменения непосредственно в сам проект, а не его копию в текущем проекте.
Теперь при сборке вашего текущего проекта в него будет включен и подключенный проект,
при этом данный проект не будет импортирован в текущий и вы можете вносить изменения
в тот подключенный проект, тогда они будут учитываться при следующей сборке во всех
проектах, в которых он подключен таким образом.
Пост на EnSO с картинками
Ответ 2
Сделайте библиотеку отдельным проектом и при компиляции публикуйте ее в каком-нибудь
репозитории. В локальном Maven, к примеру.
А в любом проекте просто подключайте ее из репозитория, как и любую другую библиотеку.
Отлаживаю приложение через USB, Android Studio не пишет ничего в logcat. Раньше все
было отлично, но сейчас вообще не идет никакой информации даже если убрать фильтры.
Копался в Функциях для разработчиков на смартфоне, ничего не нашел.
вот это я нашел:
Ответы
Ответ 1
Если вы запускаете релизную сборку приложения, то у вас, скорее всего, не прописано
в gradle debuggable true для неё.
buildTypes {
release {
debuggable true
}
}
Второй вариант включения логов в релизной сборке - указать этот атрибут в манифесте
через атрибут тега Application
android:debuggable="true"
Самый же лучший вариант - настроить варианты для сборки так, чтобы иметь возможность
включать/выключать логи для релизной сборки в разных оной вариантах так:
buildTypes {
debug {
resValue "bool", "debuggable", "true"
}
release {
}
}
productFlavors {
dev {
resValue "bool", "debuggable", "true"
}
prod {
resValue "bool", "debuggable", "false"
}
}
В манифесте укажите ссылку на сгенерированный градлом ресурс:
android:debaggable="@bool/debuggable"
Теперь вы сможете собирать devRelease сборку с включёнными логами и prodRelease с
выключенными. А debug сборки всегда будут с включёнными логами
Ответ 2
Включите это в Android Studio:
Tools -> Android -> Enable ADB Integration
В ходе разработки использую Retrofit2.
В Retrofit2 использую logger:
.client(new OkHttpClient.Builder().addInterceptor(new HttpLoggingInterceptor().setLevel(BODY)).build())//
Logging
Как мне сделать чтобы в релизной версии не было этой зависимости?
Если в Gradle я укажу Logger'у testImplementation тогда мне придется закомментировать
строку Logger'а.
Ответы
Ответ 1
Например, так:
В build.gradle описать зависимость, как
debugImplementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'
Создать файл src/debug/java/com/example/logging/LoggingInterceptor:
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import static okhttp3.logging.HttpLoggingInterceptor.Level.BODY;
public class LoggingInterceptor implements Interceptor {
private final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor().setLevel(BODY);
@Override
public Response intercept(Chain chain) throws IOException {
return interceptor.intercept(chain);
}
}
Создать файл src/release/java/com/example/logging/LoggingInterceptor:
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Response;
public class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
return chain.proceed(chain.request());
}
}
И использовать этот интерсептор в проекте:
.client(new OkHttpClient.Builder().addInterceptor(new LoggingInterceptor()).build())//
Logging
Тогда, при сборке assembleDebug будет использоваться интерсептор с логгером, а при
сборке assembleRelease будет использоваться пустой интерсептор, а библиотека с логгером
не попадет в classpath.
Ответ 2
Есть менее мудреный способ:
public class LoggingInterceptor implements Interceptor {
private final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor().setLevel(BODY);
@Override
public Response intercept(Chain chain) throws IOException {
if(BuildConfig.DEBUG)
return interceptor.intercept(chain); //в дебажной версии сработает эта ветка
else
return chain.proceed(chain.request()); //в релизной эта ветка
}
}
Ключ переменная BuildConfig.DEBUG, которая в релизе false
Например, приложение делится на три модуля: Core, Personal, Client;
В Core определены основные библиотеки и методы которые будут переиспользовать остальные
модули. Personal и Client - это модули со своим набором activity и бизнес логикой.
При авторизации пользователя выбирается, какой модуль использовать.
Подскажите, как разрешить зависимости между модулями, а так же каким образом может
происходить выбор модуля в зависимости от триггера у пользователя?
Ответы
Ответ 1
Создание модуля (библиотеки)
Для создания модуля в Android Studio выбираете
File > New > New Module
Далее есть 2 варианта. Если вы планируете создать «чистую» java-библиотеку, в качестве
типа указывайте Java Library, в итоге код такой библиотеки скомпилируется в JAR файл.
Это удобно, так как вы сможете использовать ее не только в Android приложениях. Если
же вы собираетесь использовать android-специфичные вещи и вам понадобятся классы из
пакетов android.*, то создавайте Android Library, которая при компиляции собирается
в AAR файл. В данном случае вам понядобится последний вариант.
ВАЖНО: В minSDKVersion (файлы build.gradle модулей) приложения должен совпадать или
быть больше, чем указанный в модуле библиотеки.Указанные buildToolsVersion должны быть
установлены в Android-SDK. Каждый модуль библиотеки генерирует свой класс ресурсов
(*.R.class). Когда Android библиотеки добавляются в проект и происходит его сборка,
то их ресурсы сливаются, что может привести к конфликтам. Поэтому в документации определены
следующие соглашения:
Если ID ресурса приложения совпадает с ID ресурса в библиотеке, то используется ресурс
приложения
Если ID ресурса совпадает в разных библиотеках, то используется ресурс библиотеки,
которая указана первой в списке зависимостей (находится выше в блоке dependecies)
Для избежания описанных выше конфликтов рекомендуется использовать префикс или другую
последовательную схему именования ресурсов, которая будет уникальна для каждого из
модулей (или уникальна для всего приложения вцелом)
Подключение Android библиотеки
Подключаются Android библиотеки как зависимости (если библиотека была создана как
отдельный проект в AndroidStudio).
Тут есть так же 2 варианта:
1.Либо добавить скомпилированный AAR (или JAR) файл:
- File > New Module
- Import .JAR/.AAR Package > Next
- вводите путь до ARR (или JAR) файла > Finish
2.Либо импортировать библиотеку из исходников:
- File > New > Import Module
- вводите путь до директории, в которой находятся исходники библиотеки > Finish
ВАЖНО: убедиться, что имя Android библиотеки было добавлено в settings.gradle
include ':app', ':core', ':personal', ':client'
и появилась в блоке dependencies файла build.gradle приложения
dependencies {
compile project(":core")
compile project(":personal")
compile project(":client")
}
Android библиотеки могут содержать в себе ресурсы, другие JAR библиотеки, собственный
AndroidManifest.xml.
Структура скомпилированной Android библиотеки
Скомпилированная Android библиотека представляет собой обычный zip архив с расширением
.arr, который содержит следующие обязательные файлы и директории:
/AndroidManifest.xml
/classes.jar
/res/
/R.txt
и необязательные:
/assets/
/libs/name.jar
/jni/abi_name/name.so (где abi_name один из поддерживаемых Android ABIs)
/proguard.txt
/lint.jar
Занимаюсь по книге "Android. Программирование для профессионалов". В одном из приложений,
которые там рассматриваются, сказано что мы будем использовать библиотеку support-v4.
Для этого нужно зайти в файл build.gradle. Затем перейти в File-Project Structure-app-Dependencies
и добавить библиотеку support-v4.
Я выполнил эти действия. Появилась ошибка которая в книге, видимо, не предусмотрена.
build.gradle
apply plugin: 'com.android.application'
android {
...
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.android.support:design:25.3.1'
testCompile 'junit:junit:4.12'
compile 'com.android.support:support-v4:26.0.0-alpha1'
}
Мною была добавлена только последняя строка, которая подсвечивается красной линией.
Описание ошибки:
This support library should not use a different version (26) than the compileSdkVersion (25)
Помогите пожалуйста избавиться от ошибки. Проект новый, ничего кроме этого я в нем
не менял.
Ответы
Ответ 1
У вас в приложении установлено compileSdkVersion 25, а также большая часть support
библиотек имеет версию 25.х.х, что означает их совместимость до 25 версии сдк. Но для
support-v4 вы используете версию 26.х.х. Соответственно для ее работы нужно повысить
поддерживаемую версию в вашем приложении до 26 и обновить все support библиотеки до
26 версии. Но на данный момент для вас лучшем решением будет использовать support-v4
версии 25.3.1, т.е. сделать так:
compile 'com.android.support:support-v4:25.3.1'
Ответ 2
Что бы подключить support-v4, достаточно добавить строчку в app/build.gradle, версия
библиотеки не должна отличаться от compileSdkVersion, как вам и написала IDE, замените
последнюю строчку на
compile 'com.android.support:support-v4:25.3.1'
Ответ 3
Собственно как в ошибке и написано - у вас добавилась другая версия либы, не та,
что используется для compileSdkVersion. Там 25, а у вас добавилась 26.
Просто поменяйте версию либы:
//compile 'com.android.support:support-v4:26.0.0-alpha1'
compile 'com.android.support:support-v4:25.3.1'
Ответ 4
библиотека AppCompat-v7 включает в себя зависимость support-v4 и отдельно ее подключать
еще раз не нужно.
Это написано в документации
Есть два продакт флэйвора:
productFlavors {
demo {
...
}
full {
...
}
}
и два билд тайпа:
buildTypes {
release {
...
}
debug {
...
}
}
Исходя из существующих продакт флейворов и билд тайпов получается четыре билд варианта:
demoRelease
demoDebug
fullRelease
fullDebug
Возможно ли для каждого из четырех билд вариантов в AndroidManifest.xml прописать
различные значения для некоторых атрибутов? Если возможно, то как? С помощью manifest
placeholders или как-то иначе?
Например, есть четыре API-ключа для какого-то сервиса и в зависимости от конкретного
билд варианта в AndroidManifest.xml нужно вставлять свой собственный ключ.
Сейчас у меня это реализовано с помощью отдельного strings.xml для каждого билд варианта,
но хотелось бы где-то в одном файле прописать API-ключи, а не создавать кучу дополнительных
файлов.
Интересует что-нибудь вроде этого решения (в первой части ответа).
Ответы
Ответ 1
У меня сделано это так (build.gradle):
android {
defaultConfig {
applicationId "blah-blah"
targetSdkVersion targetSdkVersionVar
}
productFlavors {
honeycumb {
minSdkVersion minSdkHoneycumb
targetSdkVersion targetSdkHoneycumb
}
kitkat {
minSdkVersion minSdkKitkat
targetSdkVersion targetSdkVersionVar
}
}
}
Остальное прописано в манифестах src/main, src/honeycumb, src/kitkat
Ответ 2
Можно дополнить вариант, предложенный вами таким образом:
build.gradle
android {
defaultConfig {
manifestPlaceholders = [ apiKey:project.property('default.ApiKey') ]
}
}
applicationVariants.all{ variant->
if (variant.productFlavors.get(0).name.equals("demo")) {
if (variant.buildType.name.equals("release")) {
manifestPlaceholders = [ apiKey:project.property('release.demo.ApiKey') ]
} else {
manifestPlaceholders = [ apiKey:project.property('debug.demo.ApiKey') ]
}
} else if (variant.productFlavors.get(0).name.equals("full")){
if (variant.buildType.name.equals("release")) {
manifestPlaceholders = [ apiKey:project.property('release.full.ApiKey') ]
} else {
manifestPlaceholders = [ apiKey:project.property('debug.full.ApiKey') ]
}
}
}
AndroidManifest.xml
gradle.properties (глобальный)
Если его нет, то необходимо создать и расположить по пути /.gradle.
release.demo.ApiKey="your_key"
debug.demo.ApiKey="your_key"
release.full.ApiKey="your_key"
debug.full.ApiKey="your_key"
default.ApiKey="your_key"
Глобальный файл нужен только если код будет загружен в публичный репозиторий, так
как он игнорируется системами контроля версий (актуально для библиотек). В противном
случае можно использовать gradle.properties проекта.
источник
При работе с Android Studio я использую сборку Gradle. Есть ли какой-то способ добавить
dependencies по-умолчанию? Например, я постоянно использую библиотеку ButterKnife и
ещё несколько. Как перестать постоянно их прописывать? Чтобы при создании проекта они
сами добавлялись.
Ответы
Ответ 1
Например, вы можете заменить дефолтный шаблон из Android Studio\plugins\android\lib\templates\gradle-projects\NewAndroidProject\root\build.gradle.ftl.
Знаю, что такой вопрос уже был, но его автор задал вопрос без подробностей и не получил
ответа.
Создал проект с библиотекой, рядом создал модуль приложения для проверки библиотеки.
Хочу все это дело тестировать с помощью Robolectric. Добавил его в зависимости. После
этого проект начал долго компилироваться. Если убрать Robolectric, все нормально собирается.
Добавление multidex в defaultConfig и подключение библиотеки support.multidex не
помогают.
Вот файл build.gradle приложения:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "imangazaliev.quickmenusample"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile project(':library')
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'org.robolectric:robolectric:3.0'
}
А еще выскакивает такая ошибка:
Information:Gradle tasks [:app:generateDebugSources, :app:generateDebugAndroidTestSources,
:app:assembleDebug]
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:library:compileLint
:library:copyReleaseLint UP-TO-DATE
:library:preBuild UP-TO-DATE
:library:preReleaseBuild UP-TO-DATE
:library:checkReleaseManifest
:library:preDebugAndroidTestBuild UP-TO-DATE
:library:preDebugBuild UP-TO-DATE
:library:preDebugUnitTestBuild UP-TO-DATE
:library:preReleaseUnitTestBuild UP-TO-DATE
:library:prepareComAndroidSupportAppcompatV72310Library UP-TO-DATE
:library:prepareComAndroidSupportSupportV42310Library UP-TO-DATE
:library:prepareReleaseDependencies
:library:compileReleaseAidl UP-TO-DATE
:library:compileReleaseRenderscript UP-TO-DATE
:library:generateReleaseBuildConfig UP-TO-DATE
:library:generateReleaseAssets UP-TO-DATE
:library:mergeReleaseAssets UP-TO-DATE
:library:generateReleaseResValues UP-TO-DATE
:library:generateReleaseResources UP-TO-DATE
:library:mergeReleaseResources UP-TO-DATE
:library:processReleaseManifest UP-TO-DATE
:library:processReleaseResources UP-TO-DATE
:library:generateReleaseSources UP-TO-DATE
:library:processReleaseJavaRes UP-TO-DATE
:library:compileReleaseJavaWithJavac UP-TO-DATE
:library:extractReleaseAnnotations UP-TO-DATE
:library:mergeReleaseProguardFiles UP-TO-DATE
:library:packageReleaseJar UP-TO-DATE
:library:compileReleaseNdk UP-TO-DATE
:library:packageReleaseJniLibs UP-TO-DATE
:library:packageReleaseLocalJar UP-TO-DATE
:library:packageReleaseRenderscript UP-TO-DATE
:library:packageReleaseResources UP-TO-DATE
:library:bundleRelease UP-TO-DATE
:app:prepareComAndroidSupportAppcompatV72310Library UP-TO-DATE
:app:prepareComAndroidSupportSupportV42310Library UP-TO-DATE
:app:prepareQuickMenuLibraryLibraryUnspecifiedLibrary UP-TO-DATE
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:preDebugAndroidTestBuild UP-TO-DATE
:app:prepareDebugAndroidTestDependencies
:app:compileDebugAndroidTestAidl UP-TO-DATE
:app:processDebugAndroidTestManifest UP-TO-DATE
:app:compileDebugAndroidTestRenderscript UP-TO-DATE
:app:generateDebugAndroidTestBuildConfig UP-TO-DATE
:app:generateDebugAndroidTestAssets UP-TO-DATE
:app:mergeDebugAndroidTestAssets UP-TO-DATE
:app:generateDebugAndroidTestResValues UP-TO-DATE
:app:generateDebugAndroidTestResources UP-TO-DATE
:app:mergeDebugAndroidTestResources UP-TO-DATE
:app:processDebugAndroidTestResources UP-TO-DATE
:app:generateDebugAndroidTestSources UP-TO-DATE
:app:processDebugJavaRes UP-TO-DATE
:app:compileDebugJavaWithJavac UP-TO-DATE
:app:compileDebugNdk UP-TO-DATE
:app:compileDebugSources UP-TO-DATE
:app:preDexDebug UP-TO-DATE
:app:dexDebug
UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:502)
at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:277)
at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:491)
at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:168)
at com.android.dx.merge.DexMerger.merge(DexMerger.java:189)
at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:502)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:334)
at com.android.dx.command.dexer.Main.run(Main.java:277)
at com.android.dx.command.dexer.Main.main(Main.java:245)
at com.android.dx.command.Main.main(Main.java:106)
Error:Execution failed for task ':app:dexDebug'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException:
Process 'command 'C:\Program Files\Java\jdk1.8.0_60\bin\java.exe'' finished with non-zero
exit value 2
Information:BUILD FAILED
Information:Total time: 18.905 secs
Information:1 error
Information:0 warnings
Information:See complete output in console
Ответы
Ответ 1
Эта ошибка, похоже, вызвана тем, что вместе с этой библиотекой вы превысили лимит
количества методов в проекте - 65536.
Решить можно:
Используя решение гугла для этой проблемы Building Apps with Over 65K Methods. Кратко:
добавьте вот это в gradle:
android {
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
Добавьте аттрибут в тег Application Manifest-a:
...
И, если используете свой класс Application то надо расширять его теперь от MultiDexApplication
Как помянуто в комментах @temq, указывать testCompile вместо compile для библиотек
которые нужны для unit тестов
Удалить все остальные библиотеки чтобы войти в лимит)
Написал библиотеку, выложил в jcenter, подцепил и заметил алерт который меня напрягает:
Ни в одной библиотеке, которую я использовал до этого не было такого алерта, следовательно
- я где-то накосячил в таске формирования -source и -javadocs артефактов.
Может кто сталкивался с этим до меня?
Скрипт формирования артефактов:
android.libraryVariants.all { variant ->
def javadocTask = task("generate${variant.name.capitalize()}Javadoc", type: Javadoc) {
description "Generates Javadoc for $variant.name."
source = variant.javaCompile.source
ext.androidJar = project.files(android.getBootClasspath().join(File.pathSeparator))
classpath = files(variant.javaCompile.classpath.files) + files(ext.androidJar)
exclude '**/BuildConfig.java'
exclude '**/R.java'
}
javadocTask.dependsOn variant.javaCompile
def jarJavadocTask = task("jar${variant.name.capitalize()}Javadoc", type: Jar) {
description "Generate Javadoc Jar for $variant.name"
classifier = 'javadoc'
from javadocTask.destinationDir
}
jarJavadocTask.dependsOn javadocTask
artifacts.add('archives', jarJavadocTask)
def jarSourceTask = task("jar${variant.name.capitalize()}Sources", type: Jar) {
description "Generates Java Sources for $variant.name."
classifier = 'sources'
from variant.javaCompile.source
}
jarSourceTask.dependsOn variant.javaCompile
artifacts.add('archives', jarSourceTask)
}
Сама библиотека: https://bintray.com/ztrap-llc/maven/FormattedEditText/
Ответы
Ответ 1
Разобрался (правда не без пары вырванных клоков волос). Косяк действительно допустил
я. Но узнать в каком именно месте, мне не удалось, т.к. на просторе GitHub'ов я позаимствовал
скрипт, который (О, чудо!) идеально отработал.
Ниже сам скрипт:
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
classpath += configurations.compile
}
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
classifier = 'javadoc'
from androidJavadocs.destinationDir
}
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.sourceFiles
}
artifacts {
archives androidSourcesJar
archives androidJavadocsJar
}
Пишу сервлет на винде, собираю проект через Gradle. Запускать надо будет на Debian.
В проекте используется путь до определённого файла в ОС (драйвер Chrome для Selenium).
На винде и Debian он разный. Как я могу настроить варианты сборки для разных ОС так,
чтобы в них была в Java коде доступна константа, заданная в скрипте сборки и имеющая
разные значения для вариантов сборки?
В андроид это сделать легко, а вот тут сходу не сообразить. Рассмотрю вариант однозначного
программного определения ОС, на коей идёт исполнение и подставление пути до файла в
рантайме.
Ответы
Ответ 1
Рассмотрю вариант однозначного программного определения ОС, на коей идёт исполнение
и подставление пути до файла в рантайме.
Насколько я понимаю для Ваших целей достаточного грубого определения ОС: Windows
и не-Windows. Тогда подойдет такой метод:
boolean isWindows() {
return System.getProperty("os.name").contains("Windows");
}
Метод можно использовать при инициализации пути, например:
//константы
private static final String WINDOWS_PATH = "C:\\driver\\chrome.exe";
private static final String UNIX_PATH = "/usr/bin/chromedriver";
...
//использование
pathToExecutable = isWindows() ? WINDOWS_PATH : UNIX_PATH;
С помощью Gradle можно записывать путь, например, в файл properties, после чего код
будет считывать его в рантайме.
Ответ 2
Если в самом скрипте Gradle то можно воспользоваться следующей конструкцией:
import org.apache.tools.ant.taskdefs.condition.Os
if (Os.isFamily(Os.FAMILY_WINDOWS) {
Тут код
}
if (Os.isFamily(Os.FAMILY_UNIX) {
И тут код
}
Заменил абсолютно все compile на implementation в gradle по рекомендации (предупреждению)
Android Studio, но предупреждение (warning) продолжает меня предупреждать:
Configuration 'compile' is obsolete and has been replaced with
'implementation'
Ответы
Ответ 1
Обновил
com.google.gms:google-services 3.1.1
на
com.google.gms:google-services 3.2.0
и все OK! Предупреждений больше нет!
Файл build.gradle выглядит следующим образом:
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.recyclerviewexample"
minSdkVersion 14
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
implementation 'androidx.recyclerview:recyclerview:1.0.0-beta01'
}
Но в результате сборки ошибки:
Information:Gradle tasks [:app:generateDebugSources, :app:generateDebugAndroidTestSources,
:app:mockableAndroidJar]
C:\Users\Xu\.gradle\caches\transforms-1\files-1.1\appcompat-1.0.0-beta01.aar\45f296cd7466b0137ad2b0b5868320be\res\values-v28\values-v28.xml
Error:(9, 5) error: resource android:attr/dialogCornerRadius not found.
C:\Users\Xu\.gradle\caches\transforms-1\files-1.1\appcompat-1.0.0-beta01.aar\45f296cd7466b0137ad2b0b5868320be\res\values\values.xml
Error:(1304, 5) error: resource android:attr/fontVariationSettings not found.
Error:(1304, 5) error: resource android:attr/ttcIndex not found.
D:\Android Projects\RecyclerViewExample\app\build\intermediates\incremental\mergeDebugResources\merged.dir\values-v28\values-v28.xml
Error:(11) error: resource android:attr/dialogCornerRadius not found.
Error:(7) resource android:attr/dialogCornerRadius not found.
Error:(11) resource android:attr/dialogCornerRadius not found.
D:\Android Projects\RecyclerViewExample\app\build\intermediates\incremental\mergeDebugResources\merged.dir\values\values.xml
Error:(231) resource android:attr/fontVariationSettings not found.
Error:(231) resource android:attr/ttcIndex not found.
Error:failed linking references.
Error:java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException:
com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception:
AAPT2 error: check logs for details
Error:com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:Execution failed for task ':app:processDebugResources'.
> Failed to execute aapt
Information:BUILD FAILED in 7s
Information:13 errors
Information:0 warnings
Information:See complete output in console
При этом, если блок dependencies выглядит так:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
}
то сборка проходит успешно. Как добавить зависимость androidx в проект? Версия Android
Studio - 3.0.1.
Ответы
Ответ 1
Согласно доке
New Project If you create a new project using the androidx-packaged
dependencies (as opposed to refactoring an existing project with the
Android Studio tool), your new project needs to target API level 28,
and you will need to add the following lines to your gradle.properties
file:
android.useAndroidX=true
android.enableJetifier=true
требуется выставить targetSdkVersion как минимум 28 и добавить явное разрешение на
использование либ из androidx пакета в файле gradle.properties:
android.useAndroidX=true
android.enableJetifier=true
Закрыт. На этот вопрос невозможно дать объективный ответ.
Ответы на него в данный момент не принимаются.
Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы на него можно было дать ответ, основанный на фактах и цитатах, отредактировав его.
Закрыт 3 года назад.
Иногда (редко но все же) пишу что-либо на Java и всегда использовал для сборки проектов
Ant. Но уже давно знаю, что есть также и Maven, и Gradle. Чем эти системы сборки лучше
или хуже по сравнению с Ant? Как-то пробовал разобраться с Maven, но пока не осилил,
тоже самое с Gradle - не понимаю в чем фишка этих систем по сравнению со старым добрым Ant.
Ответы
Ответ 1
Не знаю насчет Maven, не доводилось работать, но Gradle на 10 порядков более мощная
система сборки, чем Ant.
Конечно, если вы не используете какие то специфические алгоритмы сборки с несколькими
вариантами билдинга, не подключаете внешние библиотеки, которые находятся в сетевых
репозиториях или еще в каких то местах и разнообразных форматах, работаете не в команде,
у вас не 3 варианта приложения с немного различающимся функционалом и прочие изыски,
а только билдите одно собственное приложение в релиз - вам и кажется, что разницы нет,
но хотя бы один факт, что Gradle использует полноценный язык программирования Groovy
для создания сценария сборки, то есть вы можете написать полноценную программу, как,
из чего и при каких условиях собирать определенный билд, уже выводит его на абсолютно
другой уровень по сравнению с примитивным языком Ant.
В общем то довольно доступно о качестенных различиях той или иной системы сборки
и предоствляемых ими возможностях можно прочитать на той же википедии. Более подробно
в официальной документации.
Отвлеченно, разница между Ant и Gradle находится в таких соотношениях, как управление
автомобилем и запуск космического корабля. Вполне возможно, что ваш проект не предполагает
настолько глобальных действий, как "вывод на орбиту" (хотя Grable способен ее решить),
но и управление "таксопарком" с Ant уже определенная проблема, а это вполне "земная"
задача.
Туториалов много, но каждый охватывает только часть процесса, не могу найти простой
и понятный для новичка, охватывающий весь процесс.
Что я хочу:
Есть Java приложение (причем, это может быть как web приложение, запускаемое в том
же Tomcat, либо обычное консольное приложение или библиотека, собираемая в jar )
Написаны Unit и интеграционные тесты
Приложение собирается gradle-ом.
Развернут Artifactory с репозиторием, куда я хочу деплоить сборки.
Собственно процесс, который я хочу настроить:
При каждом пуше на сервере прогоняются unit-тесты, интеграционные тесты, анализируется
покрытие кода тестами, codestyle и т.д.
Если все хорошо, сборка деплоится в Artifactory, а также (если приложение - веб),
обновляется и перезапускается на dev сервере.
Либо иметь некоторую страничку, представляющее собой таблицу: ссылка на скачивание
- commit message (для примера: http://abrok.eu/stockfish/)
Если что-то пошло не так, ответ с описанием приходит на почту (например)
Было бы здорово посмотреть туториал с самого нуля, когда создается helloWorld Java
проект, как настраивается Jenkins, что происходит, когда делается commit и т.д. Т.е.
туториал, где одновременно с настройкой Jenkins пишется и изменяется java код.
Может быть не обязательно полностью описанный мной процесс, но какой-нибудь туториал,
который показывает упрощенно процесс разработки (изменение, написание тестов, коммиты)
java приложение при работающем jenkins.
Ответы
Ответ 1
Если сфокусироваться на организации процесса сборки средствами Jenkins, получится
примерно следующее:
При каждом пуше на сервере прогоняются unit-тесты, интеграционные тесты, анализируется
покрытие кода тестами, codestyle и т.д.
Для проекта (job) задается триггер сборки "Опрашивать SCM об изменениях" и расписание
проверки Git-а на наличие свежих коммитов, например раз в 10 минут. Расписание задается
в формате crontab: H/10 * * * *.
Другой вариант - выбрать триггер "Trigger builds remotely (e.g., from scripts)" и
настроить post-commit hook в репозитории, который будет уведомлять Jenkins о наличии
новых коммитов. Для этого достаточно дернуть curl-ом адрес http:///job//build.
Прогон тестов реализуется вызовом gradle. Установите на билдсервер Gradle Plugin
и в качестве основного шага сборки вызывайте gradle, как если бы вы запускали его на
локальной машине. Если сборка будет включать в себя прогон тестов, jenkins сохранит
информацию о результатах.
Если все хорошо, сборка деплоится в Artifactory, а также (если приложение - веб),
обновляется и перезапускается на dev сервере.
Ставите Artifactory Plugin и добавляете послесборочный шаг "Deploy artifacts to Artifactory".
Редеплой приложение лучше вынести в отдельный проект, который будет вызываться после
основной сборки через Послесборочную операцию "Build other project". Чтобы "дотянуться"
из проекта деплоя до артефактов основной сборки, установите Copy Artifacts Plugin.
Вам будет доступен шаг сборки "Copy artifacts from another project", который скопирует
нужные файлы из исходной (upstream) сборки.
Саму процедуру деплоя можно реализовать средствами Jenkins (например, Deploy Plugin),
средствами gradle (например, gradle-cargo-plugin) или просто shell-скриптом.
Если что-то пошло не так, ответ с описанием приходит на почту (например)
Это Jenkins умеет "из коробки", достаточно включить в настройках проекта флажок
"E-mail Notification". Но я рекомендую поставить Email-ext plugin - он позволяет гибче
настраивать события для письма и содержимое.
Я хочу собрать какое-то произвольное приложение, к примеру, найденное на Гитхабе:
https://github.com/heruoxin/Clip-Stack (само приложение у меня уже есть, потому не
надо мне слать ссылки на бинарные сборки)
Зачастую, в комплекте с приложением есть обертка для Gradle, иногда свойства проекта
от Eclipse, иногда ничего нет. Сам процесс, не смотря на кажущуюся простоту, достаточно
сложен: надо выкачать SDK/NDK (теперь прямых ссылок на них не дают, но об этом позже),
настроить переменные окружения и запустить ./gradlew, а после выкачивания 200-300 мегабайт
зависимостей, очень часто вылезает какая-то ошибка (к примеру о том, что нужна проприетарная
Java 8). И даже если ошибки нет, сборка может сожрать 2-3 гигабайта памяти, весь своп
и затем упасть, ссылаясь на недостаток памяти (ведь нынче все богатые и девелопят исключительно
на макбуках последнего поколения, причем все торопятся - потому все это собирается
в 10 потоков, отжирая в 10 раз больше памяти). Кроме того, такой подход не дает возможности
скомпилировать приложение на изолированной от сети машине: Android Studio Gradle без
подключения к интернет
Вопрос: как собрать приложение без использования толстых сборщиков?
Пожалуй основная проблема происходит из-за сложности разруливания зависимостей. Например,
для сборки приложения выше, мне понадобились:
support-fragment-25.2.0.aar
support-compat-25.2.0.aar
support-annotations-25.2.0.jar
support-core-utils-25.2.0.aar
support-core-ui-25.2.0.aar
appcompat-v7-22.2.1.aar
recyclerview-v7-25.2.0.aar
cardview-v7-25.2.0.aar
Но быстро выяснилось, что в 25-й версии что-то было изменено и она не подходит, скомпилированное
приложение просто падает. Я выкачал множество версий aar-пакетов и самодельными скриптами
проиндексировал их, создавая самодельную базу символов, но столкнулся с проблемой,
что в какой-то версии нет нужной фичи, а через пару версий этой фичи (или другой) уже
нет. Кроме того, не очень понятно, где и как брать официальные бинарники, без проприетарного
SDK Manager. В общем, я сдался.
Анализ поведения Gradle показал, что javac+dx не используются вообще, а aapt используется
только для обработки картинок.
Если кто-то имеет возможность/хочет написать легковестную IDE или хотя бы скрипт
для сборки приложений, то с радостью присоединюсь к проекту.
Ссылки:
https://developer.android.com/studio/build/building-cmdline.html - официальная инструкция
ведет меня к ненавистному мной Gradle
https://stackoverflow.com/questions/41132753/ - здесь кратко описывается процесс
сборки через javac+dx+aapt, дополнительный блеск от jarsigner+zipalign. Это работает
(проверял лично), однако, тут не описано как именно это сделать (впрочем, если почитать
мануалы, то становится понятно), равно как не описано, как разруливать зависимости,
что делать с ресурсами и т.д., а кроме того, как установить пакеты из SDK.
https://metacpan.org/pod/Android::Build - ссылка уже не рабочая, но в архивах можно
найти замечательный скрипт, который мог собрать простенькие приложения под Android
В вопрос призывается Lex Hobbit из Как создать модульное android приложение
Ответы
Ответ 1
Как уже написали в комментарии к вопросу - сборка и "жизнь" без Android Studio -
очень непроста. Но раз условия диктуют необходимость жить без нее, то будем адаптироваться.
Предварительная подготовка среды сборки
Java JDK
Android SDK (в самом низу страницы в разделе "Get just the command line tools")
Настройка переменных среды
JAVA_BIN путь до bin папки Java JDK
ANDROID_SDK путь до папки с Android SDK
Приватный ключ для подписи APK файла (назовем его release_key.keystore)
keytool -genkey -v -keystore release_key.keystore -alias alias_name -keyalg RSA
-keysize 2048 -validity 10000
Написать код приложения и проверить правильность структуры приложения
Пошаговый алгоритм сборки
Пошаговый алгоритм сборки Android приложения без использования gradle / ant / Android
Studio (предполагается, что весь исходный код, включая AndroidManifest.xml, ресурсы,
необходимые библиотеки у нас уже есть):
Создаем R.java, PK файл из ассетов, ресурсов и AndroidManifest.xml и получаем MyApplication.apk.unaligned
используя используя aapt package
Компилируем java исходники в *.class исполльзуя для этого javac
Создаем исполняемый файл classes.dex из *.class используя dx
Добавляем в MyApplication.apk.unaligned файл classes.dex используя aapt add
Подписываем MyApplication.apk.unaligned с дебажным или релизным ключем
Выравниваем наш APK используя zipalign и вуаля!
Создание .aar библиотеки
Алгоритм создания библиотеки .aar схож с алгоритмом создания APK файла.
в п.1 вместо R.java создаем R.txt используя aapt с опцией --output-text-symbols и
название архива с расширением *.aar
в п.3 вместо classes.dex создаем classes.jar используя
jar cvf classes.jar *.class
в п.4 добавляем classes.jar в архива с расширением *.aar и на этом все, наша отдельная
AAR библиотека создана
P/S чуть позже поправлю и можно написать скриптик для сборки.
И кажется, как бы все было проще, если бы всеже перешли к Jack&Jill, но как сообщают
разработчики - они осознали, во что это им обойдется. Ниже приведен процесс сборки
APK с использованием тулчейна Jack.
Ответ 2
Можно собрать под Intellij IDEA без Gradle. Еще пару лет назад я практиковал такое...
Врукопашную собираешь все jar/aar вручную прокидываешь зависимости и вперед.
Есть фанаты сборки Android под maven, ах ну да - это же толстый сборщик :)
Был опыт сборки под Ant - не знаю насколько он толст для ТС...
В любом случае, полностью присоединяюсь к @pavlofff:
всем сердцем полюбить Gradle в кратчайшие сроки, либо купить много валерьянки с
глицином, потому что современная сборка APK без помощи Android Studio способна "добить"
любого
Есть Java-Gradle проект. При выполнении задачи build собирается jar файл проекта
с именем artifact-1.0.jar. Нужно чтобы при каждом выполнении задачи build версия изменялась.
Пример:
artifact-1.0-1.jar.
artifact-1.0-5.jar.
artifact-1.0-20.jar.
...
artifact-1.0-N.jar.
Как правильно реализовать это?
Ответы
Ответ 1
Сначала нам нужно написать файл ant xml. Этот файл будет создавать файл, где номер
сборки будет сохранен и увеличен, а затем он просмотрит файл исходного кода ${src}/com/yourPath/Main.java
для переменной public static final String BUILD_NUMBER = ".*"; и замените ее на текущий
номер сборки.
Файл xml будет выглядеть так:
simple example increment build variable
My first ant ${src} ${line.separator}
Затем в вашем IntelliJ вы нажимаете View->Tool Windows->Ant Build. Затем + и перейдите
к вашему xml файлу (обратите внимание, что текущий путь, используемый вашим xml, станет
путем для самого файла xml, а не для проекта inteliJ, поэтому вы можете исправить часть
location="../src" в зависимости от того, где вы храните свой XML). Затем вы увидите
нашу цель init, которую вы можете выбрать, и нажмите кнопку play. Если он работает,
вы увидите BUILD_NUMBER, добавленный в исходный код Main.java. Теперь важный трюк,
как сделать это автоматически: просто щелкните правой кнопкой мыши по init и выберите
Execute on->Before Compilation. Всё, больше ничего, готово :)
Вот оригинал
Ответ 2
Вообще добавлять именно порядковый номер не лучшая идея. Т.к. при очистке сборочных
данных этот номер потеряется. Да и сканирование предыдущих версий не самая простая
задача. Лучше добавлять метку времени. В простейшем случае для Groovy DSL это делается так:
String versionSuffix = "-"+System.currentTimeMillis()
jar {
archiveVersion.set(project.version.toString() + versionSuffix)
}
Для Kotlin DSL так:
val versionSuffix: String = "-"+System.currentTimeMillis()
tasks.named("jar") {
archiveVersion.set(project.version.toString() + versionSuffix)
}
Ответ 3
Если все происходит под git + gradle (а сейчас это почти всегда так) - то я делаю
это примерно так:
1) В build.gradle определяем функцию, которая считает номер сборки (начиная от корня):
def getBuildCode = { ->
try {
def stdout = new ByteArrayOutputStream()
exec {
standardOutput = stdout
commandLine 'git', 'rev-list', '--first-parent', '--count', 'master'
}
println("Build #"+stdout)
return asInteger(stdout.toString("ASCII").trim())
}
catch (Exception e) {
e.printStackTrace();
return 0;
}
}
2) Далее в генерацию jar вставляем номер сборки:
def buildCode=getBuildCode()
task fatJar(type: Jar) {
baseName = project.name + '-' + buildCode
from { ... }
with jar
}
Я не совсем понимаю как работает Intellij Idea и как она собирает мою программу.
Можно краткий инструктаж в системы сборки и для чего они нужны?
Ещё бы хорошо, если была бы инфа неустаревшая.
Ответы
Ответ 1
TL;DR, к сожалению, не получилось.
Система сборки – это программное обеспечение, обеспечивающее автоматизацию сборки
проекта. Основное отличие от IDE в том, что конфигурационный файл для системы сборки
вы описываете в текстовом виде. Как следствие, быстрее можете начать проект, за счет
того, что что все типовые задачи заключаются в копировании уже готовых сниппетов. Это
гораздо быстрее, более гибко, мобильно, и, главное, читаемо, чем вводить то же самое
через UI диалоги IDE.
Как в общих чертах работает ваша IDE:
Когда вы создаете проект, то IDE определяет некоторые source каталоги, в которых
находятся исходные файлы вашего проекта. При запуске проекта эти файлы будут скомпилированы
и переместятся в целевую директорию. Все это, как правило, легко меняется. Можно назначить
дополнительные source каталоги, в которых IDE будет осуществлять поиск исходных файлов
или поменять целевую директорию;
Если ваш проект использует библиотеки, то вы скачиваете их, складываете в определенную
директорию, и подключаете их как зависимости вашего проекта. Таким образом IDE оповещается
о том, что при запуске проекта, эти JAR-файлы будут находиться в classpath, она сама
подставит их в ключ java –cp и начнет предоставлять типы и методы этих библиотек в
автодополнении, и делать другие удобные вещи, для которых и предназначены IDE;
Проекту назначается соответствующая JDK, компилятор которой и будет компилировать классы;
Могут назначаться некоторые дополнительные опции, такие как переменные окружения,
аргументы JVM и прочее;
IDE также может выполнять определенные задачи. Например, не только положить собранный
проект в каталог сборки, или запустить его, но задеплоить его на удаленный сервер;
Настройки проекта IDE сохраняет в своем внутреннем формате, и складывает в виде файлов,
иногда и дополнительных каталогов в директории проекта. Вся эта логика работает через
UI диалоги, которые зачастую не очевидны и плохо описаны.
Очевидные недостатки, которые из этого следуют:
если в проекте несколько участников, они все должны использовать одну и ту же IDE
и синхронизировать настройки при каждом изменении;
тыкать мышкой в кучу разных диалогов долго и неудобно;
Кроме того, если проект большой, его нужно каким-то образом поделить на модули, а
также объявить какой модуль от какого зависит. Машина разработчика
- не единственное место где нужно запускать проект - нужны конфигурации проекта для
запуска в разных средах: разработка и продакшн, как минимум. Перед сборкой проекта
также необходимо запустить интеграционные и юнит- тесты (иногда очень много), чтобы
убедиться в отсутствии багов.
Первым для автоматизации этих задач появился Ant. Это аналог make-файла, а по сути
набор скриптов (которые называются tasks). Ant – это пример императивного стиля описания
сборки проекта. Вы описываете некое действие, например, скомпилировать файлы в директории
проекта:
.. потом , скопировать их рабочую директорию
Все примеры из вики.
И вот из таких маленьких кирпичиков, поэтапно собираете весь сценарий сборки проекта.
А точнее, несколько сценариев для разных целей. Написав единожды хороший универсальный
сценарий, можно копировать его в последующие проекты.
Удобно в Ant то, что вы имеете полный и наглядный контроль над сборкой проекта, а
неудобно что вы описываете огромное количество очевидных задач, и по прежнему управляете
зависимостями проекта вручную (существует возможность подключить Ivy для управления
зависимостями).
Если вы хотите именно пошагового понимания, что делает IDE за ширмой - соберите проект
с помощью Ant.
Правда жизни состоит в том, что большие проекты используют большое число библиотек,
причем библиотека A, от которой зависит ваш проект, может в свою очередь зависеть еще
от десяти других, и из этих десяти, половина будет пересекаться с другими зависимостями,
от которых зависят ваши библиотеки, включенные в ваш проект :)
На смену Ant пришел Maven, который не такой гибкий, но значительно сокращает объем
рутинной работы. Основные особенности:
Конфигурация Maven - это один файл pom.xml;
Из коробки поддерживаются различные типы сборки: JAR, WAR, EAR;
Введена стандартная структура каталогов для проекта. Это сделано для того, чтобы
по умолчанию вам не нужно было объяснять системе сборки, где лежат исходные файлы,
ресурсы и куда их нужно переместить после компиляции;
Цикл сборки разбит на phases (фазы). Каждая фаза включает в себя определенный стандартный
сценарий, который называется goal (цель) . Упрощенно, вы указываете до какой фазы
нужно выполнить проект (например, только скомпилировать), и выполняется набор сценариев
связанных указанной и предыдущими фазами build lifecycle. Дополнительные сценарии реализуются
через плагины к Maven;
Поддерживается модульная архитектура проекта. Можно объявлять зависимости между модулями;
Поддерживаются профили. Это возможность, которая позволяется выполнять сборку проекта
для различных окружений (машин) по-разному. Например, в профиле для разработки приложения
определяются настройки и плагины, которых нет в профиле для продакшена, и наоборот.
Т.е. можно, например, иметь разные настройки для подключения к базе данных для рабочей
машины и сервера, где будет разворачиваться приложения. Или добавить профиль для развертывания
среды окружения, который содержит только плагины и скрипты, которые подготовят ваше
рабочее место при переезде с места на место. Название профиля передается как опция
(ключ -P) к сборке проекта;
Для централизованного хранения библиотек введен центральный репозиторий. Все популярные
библиотеки публикуются и периодически обновляются в центральном репозитории. Каждая
библиотека уникально идентифицируется по параметрам: groupId, artifactId, version.
Вам не нужно скачивать зависимости и хранить их где-то вместе с проектом, они объявляются
декларативно в теге dependency и скачиваются автоматически при сборке проекта.
Maven выполняет автоматическое разрешение зависимостей (так называются библиотеки,
от которых зависит ваше приложение). Таким образом, например, если библиотека A зависит
от библиотеки C, и библиотека B зависит от библиотеки C, но эти C – разных версий,
Maven автоматически включит в проект только последнюю версию C (иногда это минус, но
все настаивается). Также просто, например, проверить не появились ли новые версии для
библиотек, входящих в состав проекта:
mvn versions:display-dependency-updates
Поскольку зависимости выкачиваются автоматически, очень удобно делить проект между
участниками команды. Предположите, как-бы вы управляли большим числом зависимостей вручную;
Maven поддерживает архетипы. Это предопределенная структура проекта (шаблон) для
быстрого начала разработки приложения. При создании проекта вы можете указать архетип,
и вот уже есть некая начальная заготовка. Естественно, можно создавать собственные.
Для Maven есть огромное число полезных плагинов. Основной недостаток, которым ему
обычно пеняют, вытекает из его преимуществ. Декларативный стиль описания задач не позволяет
так же просто “подшаманить” в определенных случаях, как это делает Ant. Но и это обычно
решается через через различные плагины. Например, задачм Ant можно запускать из Maven
через antrun-plugin.
Нужно отметить, что когда вы работаете с Maven проектом в IDE, настройки извлекаются
именно из Maven. Например, через compiler-plugin проекту указывается версия JDK:
org.apache.maven.pluginsmaven-compiler-plugin1.71.7
Все IDE на сегодняшний момент хорошо хорошо работают с Maven - можно использовать
любую. UI диалог IDE для запуска Maven проекта - это обертка, при желании вы можете
работать в ним из командной строки.
За Gradle не скажу, потому что игрался, но вплотную не использовал.
Резюме: если вы учитесь или делаете тестовый проект без зависимостей на час - IDE
нормальный вариант - хотя сейчас все туториалы тоже пишутся под Maven или Gradle. Для
остального - система сборки.
Обновление:
Как вам правильно указал @Arsenicum, проект можно собрать и без участия IDE и систем
сборки. JDK (Java Development Kit), которое необходимо для разработки, как раз и состоит
из виртуальной Java машины (JRE) - это среда исполнения или рантайм, и Development
Tools - это инструменты среды разработки.
Development Tools - это набор, в основном, консольных утилит. Они находятся в директории
$JAVA_HOME/bin. Полный список тут. Умение напрямую работать с утилитами из набора Basic
Tools (особенно jar, java, javac, javadoc), несомненно поможет лучше ориентироваться
в вопросах запуска и сборки Java приложений.
Ответ 2
Главная особенность, когда вы используете ant, gradle или maven, что сборка вашего
продукта - это тоже код и вы им управляете как кодом и он хранится вместе с исходниками
вашей программы.
Т.б. для воспроизведения всех шагов по сборке проекта достаточно установить систему
сборки и получить код вашего проекта (git, svn) - после этого одна команда и ваш проект
собран, а иногда даже и запущен, а еще лучше если протестирован и задеплоин.
Есть всегда базовые стандартные примеры, которые вы можете использовать для начала
работы с этими системами (в мавен - это архитип, в gradle - это темплейты). Возмите
простой пример консольного приложения и поиграйте с ним. Попробуйте пройти все главные
шаги любого приложения - сборка, тест, деплой.
Для веб приложений этот сценарий просто чуть шире и состоит из нескольких тестов
и деплоев.
Отсюда вывод - используйте всегда gradle ) и посмотрите еще в сторону Docker и такого
понятия, как инфраструктура как код - это просто дальнейшее развитие этой идеи - все
хранить в виде кода.