I have a multi-module Java(Spring) project, which build by Gradle 6.7.1. And I use in Jetbrain IDEA to develop. The file Structure like this:
root
|--orm
| +---hibernates
|
|--web
|--mvc
|--rest
And then, I have tried some codes in my module project like below, what I get all are root path (/home/user/IdeaProjects/root/), not module path (/home/user/IdeaProjects/root/web/mvc). How can I get module path (/home/user/IdeaProjects/root/web/mvc) ?
new File("").getAbsolutePath()
Assuming for instance that your mvc project is setup like this in setting.gradle, in the root folder :
include 'mvc'
project(':mvc').projectDir = new File('./web/mvc')
Then, to get the path /home/user/IdeaProjects/root/web/mvc, just try this :
println project(':mvc').projectDir
Will prints :
/home/user/IdeaProjects/root/web/mvc
based on the answer of #ToYonos. We can do that by this:
settings.gradle gets the project path of every module.
write a key value into the info.properties in every module.
Spring Project read this properties file.
Code
Because struct of my project is:
root
|--orm
| +---mybatis
| +---jpa
| +---...
|--web
+--mvc
+--rest
+--...
So, I should loop twice to get the module name. And I exclude project without build.gradle.
file("${rootDir}").eachDir {
it.eachDirMatch(~/.*/) {
if (it.list().contains("build.gradle")) {
def moduleName = "${it.parentFile.name}:${it.name}"
println " ${moduleName}"
include moduleName
}}}
And then, read and write info.properties.
import java.nio.file.Paths
// read
def project_dir = project(":${moduleName}").projectDir
def propFile = Paths.get("${project_dir}", "src", "main","resources","info.properties").toFile()
propFile.createNewFile()
Properties props = new Properties()
propFile.withInputStream {
props.load(it)
}
// write
props.setProperty("project.dir","$project_dir")
props.store propFile.newWriter(), null
Related
I am not able to read test data from outside the src folder of project using java code. I am using bazel for testing java code.
The project hierarchy is as below:
Parent
Project1
Project2
Project3
Subproject1
Subproject2
data
Subfolder
Xyzzy.spi
Xyzzy.spl
BUILD.bazel
Src/main/java
Src/test/java
Com.test.sometest
Test1.java
Test2.java
BUILD.bazel
data/subfolder/BUILD.bazel:
exports_files(["Xyzzy.spi", "Xyzzy.spl"])
src/test/java/Com/test/sometest/BUILD.bazel:
load(
"//bazel:defs.bzl",
"java_library",
"java_test",
"java_binary",
)
java_test(
name = “subproject2”,
test_library = "subproject2_lib",
)
java_binary(
name = "example",
data = [
“//project3/subproject2/data/subfolder: Xyzzy.spi",
“//project3/subproject2/data/subfolder: Xyzzy.spl”,
],
runtime_deps = [":subproject2_lib"],
)
java_library(
name = "subproject2_lib",
testonly = True,
srcs = glob(
[
"*.java",
],
),
deps = [
"//:lombok",
“Path to point to build bazel of main java code”,
"#maven//:com_google_guava_guava",
"#maven//:commons_io_commons_io",
"#bazel_tools//tools/java/runfiles:runfiles",
"#maven//:junit_junit",
],
)
And java code to get path to file:
private static File CURRENT_INDEX_FILE=Paths.get("data/subfolder/Xyzzy.spi").toFile();
I am getting FileNotFoundException when running bazel test. Not sure where am doing it wrong. I tried google about this but no similar cases i found, mostly they have Maven Standard hierarchy but what should i change for this folder structure to work with.
Thanks
I am new to Gradle and trying to migrate an existing system build from ant to Gradle.
As part of this I need to run a java program on every file in a directory. Directory contains xml files and the java code will parse and convert .xml to .java files (and these Java files would be build to generate class and package in final jar) after performing some business specific transformation.
below is a function I wrote in Gradle
private runJavaFile(String dirPath) {
FileTree tree = fileTree(dir: dirPath, include: '**/*.xml')
tree.each {
def xmlfile = it.path
def javaFile = it.path.replaceFirst(".xml", ".java")
javaexec { //// getting error on this line
classpath configurations.all
main = 'XmlToJavaParser'
args = ["$xmlfile", "$javaFile", 'Java']
}
}
}
I am calling this function from a Gradle task by passing the dir path which contains the xml files to be parsed.
While running the task, I am getting below error:
> Resolving configuration 'apiElements' directly is not allowed
Any help would be appreciated.
Let me know if any more information is needed.
In Gradle, a configuration represents a group of artifacts and their dependencies. You typically have several configurations depending on what you want to do. For instance, you could have one where you declare which dependencies are needed for compilation, which are only needed at runtime, or which are needed for running a particular Java application.
In your case, you are saying that the classpath to the XmlToJavaParser class is "all configurations combined" and that doesn't really make sense. You are also not allowed to do that as some configurations from the Java plugin are not resolvable like this, which is why you get an error.
So to fix it, you should declare your own configuration for XmlToJavaParser. You can then declare dependencies for it like you normally do. Example (using the Groovy DSL):
configurations {
xmlJavaParser {
canBeResolved = true
canBeConsumed = false
}
}
dependencies {
xmlJavaParser "org.example:xml-java-parser:1.0" // or whatever you need
}
private runJavaFile(String dirPath) {
// ...
javaexec {
classpath = configurations.xmlJavaParser // The configuration is referenced here
main = 'XmlToJavaParser'
args = ["$xmlfile", "$javaFile", 'Java']
}
}
There are also other ways to go about it. But the main point is to not use configurations.all as a classpath.
Is there a way to specify the main-class of the jar in its manifest file as a parameter in Groovy's AntBuilder?
def jAnt = project.createAntBuilder();
jAnt.jar(
basedir: build_dir + "/classes", //I have only one class with the main method in it
destfile: build_dir + "/jar/test-jar.jar"
)
I just want to specify the main class here while creating the jar.
all documentation about ant tasks: https://ant.apache.org/manual/anttaskslist.html
and for jar task there are a lot of examples including Main-Class specification
you just need to create corresponding groovy-builder code
def ant = new AntBuilder()
def build_dir = "/11/git/myprj/build"
ant.jar( basedir: "${build_dir}/classes", destfile: "${build_dir}/test-jar.jar"){
manifest{
attribute(name: "Built-By", value: "me, myself" )
attribute(name: "Main-Class", value: "myPackage.MyClass" )
}
}
I would like to use the Gradle "application" plugin to create startScripts for a second mainClass. Is this possible? Even if the application plugin doesn't have this functionality built in, is it possible to leverage the startScripts task to create a second pair of scripts for a different mainClass?
Add something like this to your root build.gradle:
// Creates scripts for entry points
// Subproject must apply application plugin to be able to call this method.
def createScript(project, mainClass, name) {
project.tasks.create(name: name, type: CreateStartScripts) {
outputDir = new File(project.buildDir, 'scripts')
mainClassName = mainClass
applicationName = name
classpath = project.tasks[JavaPlugin.JAR_TASK_NAME].outputs.files + project.configurations.runtimeClasspath
}
project.tasks[name].dependsOn(project.jar)
project.applicationDistribution.with {
into("bin") {
from(project.tasks[name])
fileMode = 0755
}
}
}
Then call it as follows either from the root or from subprojects:
// The next two lines disable the tasks for the primary main which by default
// generates a script with a name matching the project name.
// You can leave them enabled but if so you'll need to define mainClassName
// And you'll be creating your application scripts two different ways which
// could lead to confusion
startScripts.enabled = false
run.enabled = false
// Call this for each Main class you want to expose with an app script
createScript(project, 'com.foo.MyDriver', 'driver')
I combined parts of both of these answers to arrive at the relatively simple solution:
task otherStartScripts(type: CreateStartScripts) {
description "Creates OS specific scripts to call the 'other' entry point"
classpath = startScripts.classpath
outputDir = startScripts.outputDir
mainClassName = 'some.package.app.Other'
applicationName = 'other'
}
distZip {
baseName = archivesBaseName
classifier = 'app'
//include our extra start script
//this is a bit weird, I'm open to suggestions on how to do this better
into("${baseName}-${version}-${classifier}/bin") {
from otherStartScripts
fileMode = 0755
}
}
startScripts is created when the application plugin is applied.
You can create multiple tasks of type CreateStartScripts and in each task you configure a different mainClassName. for convenience, you can do this in a loop.
Some Snippet of my code is shown as below;
String log4jConfigPath = FileUtil.getFilePathFromClasspath("log4j.properties");
if (null != log4jConfigPath) {
PropertyConfigurator.configureAndWatch(log4jConfigPath);
} else {
logger.warn("log4j.properties not found on classpath!");
}
Config config = Config.getConfig("crawler.properties");
String mode = config.getString("crawler.mode").toLowerCase();
I m getting an error for both the files "log4j.properties" and "crawler.properties" not found in class path..i have this files residing in folders in my projects..Can someone please tell me how to add this files to class path compiler looks for both this properties files.
Thanks;
The folder, that contains log4j.properties has to be added to the classpath, either relative to your current working directory or absolute:
/
+-project
+-src
| +-com
| +-example
| +-Hello
+-resource
+-log4j.properties
now, if you current directory is /project, then you have to run your app with
java -cp src;resource com.example.Hello # relative paths
java -cp /project/src;/project/resource com.example.Hello # absolute paths