Neovim setting up jdtls with lsp-zero/mason - java

As part of the upcoming 2023 new year I wanted to try and move my development environment to vim or neovim. I have gone through a bit of setup already and have go and js/ts setup and appearing to work just fine. Autocomplete, linting and import management.
Trying to get lsp-zero and java working though is turning out to be a nightmare (because of course java would be a problem child). I opened a java file lsp-zero was baller and asked to install the jdtls which appears to have worked and voila nothing... I just have code highlighting. No auto-complete or importing management.
I added the following to test
-- configure an individual server
lsp.configure('jdtls', {
flags = {
debounce_text_changes = 150,
},
on_attach = function(client, bufnr)
print('lsp server (jdtls) attached')
end
})
lsp.configure('gopls', {
flags = {
debounce_text_changes = 150,
},
on_attach = function(client, bufnr)
print('lsp server (gopls) attached')
end
})
Java is not picking up the lsp server
Go picks up just fine
Does anyone know of additional configs that are needed. I am not seeing anything specifically called out.
--- Config edit ---
I updated the config to call the windows version of the scripts. I also added a data path and root_dir. The lsp still never triggers.
require'lspconfig'.jdtls.setup{
cmd = {
'jdtls-win.cmd',
"-configuration",
"C:\\Users\\Coury\\AppData\\Local\\nvim-data\\mason\\packages\\jdtls\\config_win",
"-jar",
"C:\\Users\\Coury\\AppData\\Local\\nvim-data\\mason\\packages\\jdtls\\plugins\\org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar",
"-data",
"C:\\Users\\Coury\\Documents\\Code\\interviews\\truleo\\app",
},
single_file_support = true,
root_dir = function()
return "C:\\Users\\Coury\\Documents\\Code\\interviews\\truleo\\app"
end,
flags = {
debounce_text_changes = 150,
},
on_attach = function(client, bufnr)
print('lsp server (jdtls) attached')
end
}

First, include java path to your bashrc. And retry the installation using Mason.nvim
Else: Do below
Install eclipse.jdt.ls by following their Installation instructions.
Add the plugin:
vim-plug: Plug mfussenegger/nvim-jdtls
packer.nvim: use mfussenegger/nvim-jdtls
To solve this you'd have to create your personal jdlts config file in your plugins directory like so
-- Java.lua
local config = {
cmd = {
--
"java", -- Or the absolute path '/path/to/java11_or_newer/bin/java'
"-Declipse.application=org.eclipse.jdt.ls.core.id1",
"-Dosgi.bundles.defaultStartLevel=4",
"-Declipse.product=org.eclipse.jdt.ls.core.product",
"-Dlog.protocol=true",
"-Dlog.level=ALL",
"-Xms1g",
"--add-modules=ALL-SYSTEM",
"--add-opens",
"java.base/java.util=ALL-UNNAMED",
"--add-opens",
"java.base/java.lang=ALL-UNNAMED",
--
"-jar",
"/path/to/jdtls_install_location/plugins/org.eclipse.equinox.launcher_VERSION_NUMBER.jar",
"-configuration", "/path/to/jdtls_install_location/config_SYSTEM",
"-data", "/Users/YOUR_MACHINE_NAME/local/share/nvim/java"
},
settings = {
java = {
signatureHelp = {enabled = true},
import = {enabled = true},
rename = {enabled = true}
}
},
init_options = {
bundles = {}
}
}
Source the new config and open any java file.

I recommend using mfussenegger/nvim-jdtls to run and configure the language server.
Its simply a matter of setting up a FTPlugin for java that calls jdtls.start_or_attach(jdtls_config) whenever a java file/repo is opened which will start the language server and attach it to your buffer which can be verified by :LspInfo.
ftplugin/java.lua:
local jdtls_config = require("myconfig.lsp.jdtls").setup()
local pkg_status, jdtls = pcall(require,"jdtls")
if not pkg_status then
vim.notify("unable to load nvim-jdtls", "error")
return
end
jdtls.start_or_attach(jdtls_config)
and the corresponding config using jdtls (installed via mason)
You may want to provide your own capabilities and on_attach functions but otherwise it should give you a good nudge in the right direction.
myconfig/lsp/jdtls.lua
local opts = {
cmd = {},
settings = {
java = {
signatureHelp = { enabled = true },
completion = {
favoriteStaticMembers = {},
filteredTypes = {
-- "com.sun.*",
-- "io.micrometer.shaded.*",
-- "java.awt.*",
-- "jdk.*",
-- "sun.*",
},
},
sources = {
organizeImports = {
starThreshold = 9999,
staticStarThreshold = 9999,
},
},
codeGeneration = {
toString = {
template = "${object.className}{${member.name()}=${member.value}, ${otherMembers}}",
},
useBlocks = true,
},
configuration = {
runtimes = {
{
name = "JavaSE-1.8",
path = "/Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home",
default = true,
},
{
name = "JavaSE-17",
path = "/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home",
},
{
name = "JavaSE-19",
path = "/Library/Java/JavaVirtualMachines/jdk-19.jdk/Contents/Home",
},
},
},
},
},
}
local function setup()
local pkg_status, jdtls = pcall(require,"jdtls")
if not pkg_status then
vim.notify("unable to load nvim-jdtls", "error")
return {}
end
-- local jdtls_path = vim.fn.stdpath("data") .. "/mason/packages/jdtls"
local jdtls_bin = vim.fn.stdpath("data") .. "/mason/bin/jdtls"
local root_markers = { ".gradle", "gradlew", ".git" }
local root_dir = jdtls.setup.find_root(root_markers)
local home = os.getenv("HOME")
local project_name = vim.fn.fnamemodify(root_dir, ":p:h:t")
local workspace_dir = home .. "/.cache/jdtls/workspace/" .. project_name
opts.cmd = {
jdtls_bin,
"-data",
workspace_dir,
}
local on_attach = function(client, bufnr)
jdtls.setup.add_commands() -- important to ensure you can update configs when build is updated
-- if you setup DAP according to https://github.com/mfussenegger/nvim-jdtls#nvim-dap-configuration you can uncomment below
-- jdtls.setup_dap({ hotcodereplace = "auto" })
-- jdtls.dap.setup_dap_main_class_configs()
-- you may want to also run your generic on_attach() function used by your LSP config
end
opts.on_attach = on_attach
opts.capabilities = vim.lsp.protocol.make_client_capabilities()
return opts
end
return { setup = setup }
These examples are yanked from my personal neovim config (jdtls config). Hope this helps get you rolling.
Also make sure you have jdk17+ available for jdtls (i launch neovim with JAVA_HOME set to my jdk17 install)
(your code can still be compiled by and run on jdk8 -- I successfully work on gradle projects that are built with jdk8 no problems w/ this config)

Related

Bazel equivalent of Buck's classpath

I'm trying to migrate a project from buck to bazel and looking for an equivalent of the $(classpath) macro available for genrules. Is there anything similar available in bazel to get a list of jars for the classpath of a given java_library?
The best I could come up with is iterating over the list of dependencies and using the $(execpath) macro to get the correspondent jar:
jar_deps = []
for dep in deps: # deps are the same dependencies specified for the java_library
jar_deps.append("$(execpath %s)" % dep)
genrule(
name = "test-rule",
outs = ["test-rule.txt"],
deps = deps,
cmd = "echo \"%s\" > $#" % (":".join(jar_deps)),
)
Is there a better way?
It looks like another way to achieve this is by using a custom rule accessing the Java rule's JavaInfo provider:
def _runtime_deps_providing_rule_impl(ctx):
return [
platform_common.TemplateVariableInfo({
"RUNTIME_DEPS": ":".join([f.path for f in ctx.attr.rule[JavaInfo].transitive_runtime_deps.to_list()]),
})
]
runtime_deps_providing_rule = rule(
implementation = _runtime_deps_providing_rule_impl,
attrs = {
"rule": attr.label(),
},
)
runtime_deps_providing_rule(
name = "test-providing-rule",
rule = ":test-java-rule",
)
genrule(
name = "test-rule",
outs = ["test-rule.txt"],
cmd = "echo \"$(RUNTIME_DEPS)\" > $#",
toolchains = [":test-providing-rule"],
)
The advantage of this is that there is no need to explicitly pass the list of dependencies around.

What format is this file written on?

I'm messing around with Auctionator (a WoW addon for the auction house). My application is still in development but out of curious i want to know the name for this format.
D:\Blizzard\World of Warcraft\WTF\Account\54621418#1\SavedVariables\Auctionator.lua
AUCTIONATOR_PRICE_DATABASE = {
["__dbversion"] = 4,
["Ragnaros_Horde"] = {
["Kraken's Eye of Agility"] = {
["mr"] = 6019998,
["cc"] = 3,
["H2935"] = 6019998,
["id"] = "153708:0:0:0:0",
["sc"] = 1,
},
["Tidespray Linen Pants of the Harmonious"] = {
["mr"] = 2930810,
["sc"] = 1,
["id"] = "154689:0:0:0:1715",
["L2926"] = 2930810,
["H2926"] = 19698294,
["cc"] = 4,
},
},
}
I ended up parsing the file with lots of indexOf(..) and Patters and Matchers because i couldn't find this format anywhere. Here's a screenshot of the application if you wanna see it.
A LUA file is a source code file written in Lua, a light-weight programming language designed for extending applications. It can be compiled into a program using an ANSI C compiler.
Your file looks like a table/config details
More you can have a look on https://en.wikipedia.org/wiki/Lua_(programming_language)

How to change the bootclasspath?

In a project I use Bazel 0.11.1 running Oracle Java 8 to produce Java 7 compatible .class files. While there are other ways to achieve this, I simply added the necessary source/target options with --javacopt to my .bazelrc.
This works fine, but it is good practice to change the bootclasspath as well, in order to avoid unwanted dependencies to creep in. But how do I achieve this with Bazel?
Adding -bootclasspath to --javacopt does not seem to take effect. So it seems I would have to resort to a custom java_toolchain, but I'm having trouble to get it running at all!
java_toolchain(
name = "__jdk7",
bootclasspath = ["#bazel_tools//tools/jdk:bootclasspath"],
encoding = "UTF-8",
extclasspath = ["#bazel_tools//tools/jdk:extclasspath"],
genclass = ["#bazel_tools//tools/jdk:genclass"],
header_compiler = ["#bazel_tools//tools/jdk:turbine"],
ijar = ["#bazel_tools//tools/jdk:ijar"],
javabuilder = ["#bazel_tools//tools/jdk:javabuilder"],
javac = ["#bazel_tools//third_party/java/jdk/langtools:javac_jar"],
javac_supports_workers = True,
jvm_opts = [
"-XX:+TieredCompilation",
"-XX:TieredStopAtLevel=1",
],
singlejar = ["#bazel_tools//tools/jdk:singlejar"],
source_version = "8",
target_version = "8",
visibility = ["//visibility:public"],
)
yields
Exception in thread "main" java.lang.NoSuchFieldError: ANNOTATION_PROCESSOR_MODULE_PATH
at com.sun.tools.javac.file.Locations.initHandlers(Locations.java:1976)
at com.sun.tools.javac.file.Locations.<init>(Locations.java:145)
at com.sun.tools.javac.file.BaseFileManager.createLocations(BaseFileManager.java:115)
at com.sun.tools.javac.file.BaseFileManager.<init>(BaseFileManager.java:76)
at com.sun.tools.javac.file.JavacFileManager.<init>(JavacFileManager.java:147)
at com.sun.tools.javac.file.JavacFileManager.lambda$preRegister$0(JavacFileManager.java:139)
at com.sun.tools.javac.util.Context.get(Context.java:150)
at com.sun.tools.javac.util.Context.get(Context.java:187)
at com.sun.tools.javac.comp.Enter.<init>(Enter.java:140)
at com.sun.tools.javac.comp.Enter.instance(Enter.java:112)
at com.sun.tools.javac.comp.DeferredAttr.<init>(DeferredAttr.java:109)
at com.sun.tools.javac.comp.DeferredAttr.instance(DeferredAttr.java:99)
at com.sun.tools.javac.comp.Resolve.<init>(Resolve.java:123)
at com.sun.tools.javac.comp.Resolve.instance(Resolve.java:159)
at com.sun.tools.javac.comp.Check.<init>(Check.java:116)
at com.sun.tools.javac.comp.Check.instance(Check.java:104)
at com.sun.tools.javac.comp.Modules.<init>(Modules.java:184)
at com.sun.tools.javac.comp.Modules.instance(Modules.java:174)
at com.sun.tools.javac.code.Symtab.<init>(Symtab.java:481)
at com.sun.tools.javac.code.Symtab.instance(Symtab.java:88)
at com.sun.tools.javac.comp.Attr.<init>(Attr.java:128)
at com.sun.tools.javac.comp.Attr.instance(Attr.java:119)
at com.sun.tools.javac.comp.Annotate.<init>(Annotate.java:105)
at com.sun.tools.javac.comp.Annotate.instance(Annotate.java:80)
at com.sun.tools.javac.jvm.ClassReader.<init>(ClassReader.java:252)
at com.sun.tools.javac.jvm.ClassReader.instance(ClassReader.java:245)
at com.sun.tools.javac.code.ClassFinder.<init>(ClassFinder.java:183)
at com.sun.tools.javac.code.ClassFinder.instance(ClassFinder.java:176)
at com.sun.tools.javac.main.JavaCompiler.<init>(JavaCompiler.java:379)
at com.google.devtools.build.buildjar.javac.BlazeJavaCompiler.<init>(BlazeJavaCompiler.java:41)
at com.google.devtools.build.buildjar.javac.BlazeJavaCompiler.<init>(BlazeJavaCompiler.java:32)
at com.google.devtools.build.buildjar.javac.BlazeJavaCompiler$1.make(BlazeJavaCompiler.java:76)
at com.google.devtools.build.buildjar.javac.BlazeJavaCompiler$1.make(BlazeJavaCompiler.java:67)
at com.sun.tools.javac.util.Context.get(Context.java:150)
at com.sun.tools.javac.main.JavaCompiler.instance(JavaCompiler.java:110)
at com.google.devtools.build.buildjar.javac.BlazeJavacMain.compile(BlazeJavacMain.java:117)
at com.google.devtools.build.buildjar.SimpleJavaLibraryBuilder$2.invokeJavac(SimpleJavaLibraryBuilder.java:121)
at com.google.devtools.build.buildjar.ReducedClasspathJavaLibraryBuilder.compileSources(ReducedClasspathJavaLibraryBuilder.java:54)
at com.google.devtools.build.buildjar.SimpleJavaLibraryBuilder.compileJavaLibrary(SimpleJavaLibraryBuilder.java:124)
at com.google.devtools.build.buildjar.SimpleJavaLibraryBuilder.run(SimpleJavaLibraryBuilder.java:132)
at com.google.devtools.build.buildjar.BazelJavaBuilder.processRequest(BazelJavaBuilder.java:105)
at com.google.devtools.build.buildjar.BazelJavaBuilder.runPersistentWorker(BazelJavaBuilder.java:67)
at com.google.devtools.build.buildjar.BazelJavaBuilder.main(BazelJavaBuilder.java:45)
Am I doing something wrong?
Try using default_java_toolchain:
load("#bazel_tools//tools/jdk:default_java_toolchain.bzl", "default_java_toolchain")
default_java_toolchain(
name = "__jdk7",
jvm_opts = [
"-Xbootclasspath/p:$(location #bazel_tools//third_party/java/jdk/langtools:javac_jar)",
"-XX:+TieredCompilation",
"-XX:TieredStopAtLevel=1",
],
javac = ["#bazel_tools//third_party/java/jdk/langtools:javac_jar",],
bootclasspath = ["#bazel_tools//tools/jdk:platformclasspath.jar",],
visibility = ["//visibility:public",],
source_version = "7",
target_version = "7",
)
In your .bazelrc file add a reference to the toolchain, e.g.,
build --java_toolchain=//:__jdk7
test --java_toolchain=//:__jdk7
This is the working solution:
default_java_toolchain(
name = "jdk7",
jvm_opts = [
"-Xbootclasspath/p:$(location #bazel_tools//third_party/java/jdk/langtools:javac_jar)",
"-XX:+TieredCompilation",
"-XX:TieredStopAtLevel=1",
],
javac = ["#bazel_tools//third_party/java/jdk/langtools:javac_jar"],
bootclasspath = ["jdk7.jar"],
visibility = ["//visibility:public"],
source_version = "7",
target_version = "7",
)
jdk7.jar has been manually created with the help of DumpPlatformClassPath.java provided below bazel_tools/tools/jdk.

How can you get 1.7-compatible output for a java_proto_library?

For a java_library, I can set the javacopts attribute on the build rule. There doesn't appear to be anything similar for java_proto_library or java_lite_proto_library.
I can work around this by setting -source and -target options to javac via the -javacopt flag to bazel, but I'd rather have it encoded in the BUILD files.
You could add a JDK7 toolchain and then build everything with it. E.g., add this to a BUILD file:
java_toolchain(
name = "jdk7",
bootclasspath = ["#bazel_tools//tools/jdk:bootclasspath"],
encoding = "UTF-8",
extclasspath = ["#bazel_tools//tools/jdk:extdir"],
genclass = ["#bazel_tools//tools/jdk:GenClass_deploy.jar"],
header_compiler = ["#bazel_tools//tools/jdk:turbine_deploy.jar"],
ijar = ["#bazel_tools//tools/jdk:ijar"],
javabuilder = ["#bazel_tools//tools/jdk:JavaBuilder_deploy.jar"],
javac = ["#bazel_tools//third_party/java/jdk/langtools:javac_jar"],
javac_supports_workers = 1,
jvm_opts = [
"-XX:+TieredCompilation",
"-XX:TieredStopAtLevel=1",
],
singlejar = ["#bazel_tools//tools/jdk:SingleJar_deploy.jar"],
source_version = "7",
target_version = "7",
visibility = ["//visibility:public"],
)
And then build with:
bazel build --java_toolchain=//whatever:jdk7 //your:target

How to read a properties files and use the values in project Gradle script?

I am working on a Gradle script where I need to read the local.properties file and use the values in the properties file in build.gradle. I am doing it in the below manner. I ran the below script and it is now throwing an error, but it is also not doing anything like creating, deleting, and copying the file. I tried to print the value of the variable and it is showing the correct value.
Can someone let me know if this is the correct way to do this? I think the other way is to define everything in the gradle.properties and use it in the build.gradle. Can someone let me know how could I access the properties in build.gradle from build.properties?
build.gradle file:
apply plugin: 'java'
// Set the group for publishing
group = 'com.true.test'
/**
* Initializing GAVC settings
*/
def buildProperties = new Properties()
file("version.properties").withInputStream {
stream -> buildProperties.load(stream)
}
// If jenkins build, add the jenkins build version to the version. Else add snapshot version to the version.
def env = System.getenv()
if (env["BUILD_NUMBER"]) buildProperties.test+= ".${env["BUILD_NUMBER"]}"
version = buildProperties.test
println "${version}"
// Name is set in the settings.gradle file
group = "com.true.test"
version = buildProperties.test
println "Building ${project.group}:${project.name}:${project.version}"
Properties properties = new Properties()
properties.load(project.file('build.properties').newDataInputStream())
def folderDir = properties.getProperty('build.dir')
def configDir = properties.getProperty('config.dir')
def baseDir = properties.getProperty('base.dir')
def logDir = properties.getProperty('log.dir')
def deployDir = properties.getProperty('deploy.dir')
def testsDir = properties.getProperty('tests.dir')
def packageDir = properties.getProperty('package.dir')
def wrapperDir = properties.getProperty('wrapper.dir')
sourceCompatibility = 1.7
compileJava.options.encoding = 'UTF-8'
repositories {
maven { url "http://arti.oven.c:9000/release" }
}
task swipe(type: Delete) {
println "Delete $projectDir/${folderDir}"
delete "$projectDir/$folderDir"
delete "$projectDir/$logDir"
delete "$projectDir/$deployDir"
delete "$projectDir/$packageDir"
delete "$projectDir/$testsDir"
mkdir("$projectDir/${folderDir}")
mkdir("projectDir/${logDir}")
mkdir("projectDir/${deployDir}")
mkdir("projectDir/${packageDir}")
mkdir("projectDir/${testsDir}")
}
task prepConfigs(type: Copy, overwrite:true, dependsOn: swipe) {
println "The name of ${projectDir}/${folderDir} and ${projectDir}/${configDir}"
from('${projectDir}/${folderDir}')
into('${projectDir}/$configDir}')
include('*.xml')
}
build.properties file:
# -----------------------------------------------------------------
# General Settings
# -----------------------------------------------------------------
application.name = Admin
project.name = Hello Cool
# -----------------------------------------------------------------
# ant build directories
# -----------------------------------------------------------------
sandbox.dir = ${projectDir}/../..
reno.root.dir=${sandbox.dir}/Reno
ant.dir = ${projectDir}/ant
build.dir = ${ant.dir}/build
log.dir = ${ant.dir}/logs
config.dir = ${ant.dir}/configs
deploy.dir = ${ant.dir}/deploy
static.dir = ${ant.dir}/static
package.dir = ${ant.dir}/package
tests.dir = ${ant.dir}/tests
tests.logs.dir = ${tests.dir}/logs
external.dir = ${sandbox.dir}/FlexCommon/External
external.lib.dir = ${external.dir}/libs
If using the default gradle.properties file, you can access the properties directly from within your build.gradle file:
gradle.properties:
applicationName=Admin
projectName=Hello Cool
build.gradle:
task printProps {
doFirst {
println applicationName
println projectName
}
}
If you need to access a custom file, or access properties which include . in them (as it appears you need to do), you can do the following in your build.gradle file:
def props = new Properties()
file("build.properties").withInputStream { props.load(it) }
task printProps {
doFirst {
println props.getProperty("application.name")
println props.getProperty("project.name")
}
}
Take a look at this section of the Gradle documentation for more information.
Edit
If you'd like to dynamically set up some of these properties (as mentioned in a comment below), you can create a properties.gradle file (the name isn't important) and require it in your build.gradle script.
properties.gradle:
ext {
subPath = "some/sub/directory"
fullPath = "$projectDir/$subPath"
}
build.gradle
apply from: 'properties.gradle'
// prints the full expanded path
println fullPath
We can use a separate file (config.groovy in my case) to abstract out all the configuration.
In this example, we're using three environments viz.,
dev
test
prod
which has properties serverName, serverPort and resources. Here we're expecting that the third property resources may be same in multiple environments and so we've abstracted out that logic and overridden in the specific environment wherever necessary:
config.groovy
resources {
serverName = 'localhost'
serverPort = '8090'
}
environments {
dev {
serverName = 'http://localhost'
serverPort = '8080'
}
test {
serverName = 'http://www.testserver.com'
serverPort = '5211'
resources {
serverName = 'resources.testserver.com'
}
}
prod {
serverName = 'http://www.productionserver.com'
serverPort = '80'
resources {
serverName = 'resources.productionserver.com'
serverPort = '80'
}
}
}
Once the properties file is ready, we can use the following in build.gradle to load these settings:
build.gradle
loadProperties()
def loadProperties() {
def environment = hasProperty('env') ? env : 'dev'
println "Current Environment: " + environment
def configFile = file('config.groovy')
def config = new ConfigSlurper(environment).parse(configFile.toURL())
project.ext.config = config
}
task printProperties {
println "serverName: $config.serverName"
println "serverPort: $config.serverPort"
println "resources.serverName: $config.resources.serverName"
println "resources.serverPort: $config.resources.serverPort"
}
Let's run these with different set of inputs:
gradle -q printProperties
Current Environment: dev
serverName: http://localhost
serverPort: 8080
resources.serverName: localhost
resources.serverPort: 8090
gradle -q -Penv=dev printProperties
Current Environment: dev
serverName: http://localhost
serverPort: 8080
resources.serverName: localhost
resources.serverPort: 8090
gradle -q -Penv=test printProperties
Current Environment: test
serverName: http://www.testserver.com
serverPort: 5211
resources.serverName: resources.testserver.com
resources.serverPort: 8090
gradle -q -Penv=prod printProperties
Current Environment: prod
serverName: http://www.productionserver.com
serverPort: 80
resources.serverName: resources.productionserver.com
resources.serverPort: 80
Another way... in build.gradle:
Add :
classpath 'org.flywaydb:flyway-gradle-plugin:3.1'
And this :
def props = new Properties()
file("src/main/resources/application.properties").withInputStream { props.load(it) }
apply plugin: 'flyway'
flyway {
url = props.getProperty("spring.datasource.url")
user = props.getProperty("spring.datasource.username")
password = props.getProperty("spring.datasource.password")
schemas = ['db_example']
}
This is for Kotlin DSL (build.gradle.kts):
import java.util.*
// ...
val properties = Properties().apply {
load(rootProject.file("my-local.properties").reader())
}
val prop = properties["myPropName"]
In Android projects (when applying the android plugin) you can also do this:
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
// ...
val properties = gradleLocalProperties(rootDir)
val prop = properties["propName"]
Just had this issue come up today. We found the following worked both locally and in our pipeline:
In build.gradle:
try {
apply from: 'path/name_of_external_props_file.properties'
} catch (Exception e) {}
This way when an external props file which shouldn't get committed to Git or whatever (as in our case) you are using is not found in the pipeline, this 'apply from:' won't throw an error in it. In our use case we have a file with a userid and password that should not get committed to Git. Aside from the problem of file-reading: we found that the variables we had declared in the external file, maven_user and maven_pass, had in fact to be declared in gradle.properties. That is they simply needed to be mentioned as in:
projectName=Some_project_name
version=1.x.y
maven_user=
maven_pass=
We also found that in the external file we had to put single-quotes around these values too or Gradle got confused. So the external file looked like this:
maven_user='abc123'
maven_pass='fghifh7435bvibry9y99ghhrhg9539y5398'
instead of this:
maven_user=abc123
maven_pass=fghifh7435bvibry9y99ghhrhg9539y5398
That's all we had to do and we were fine. I hope this may help others.

Categories