Maven Ant deploy - OutOfMemoryError: Java heap space - maven

Scenario
While using the Maven Ant Task artifact:deploy, I'm encountering the error java.lang.OutOfMemoryError: Java heap space.
I'm only getting the error if the size of the file being deployed is greater than 25 MB. My artifacts are not greater than 50 MB in size.
What could the reason be? And, what can I do to fix it?
Code snippet
<artifact:deploy file="#{app.name}.jar">
<pom file="#{pom.file}"/>
<remoteRepository url="http://xxx.com:xxx/xxx-webapp/content/repositories/xxx-releases/">
<authentication username="xxx" password="xxx" />
</remoteRepository>
</artifact:deploy>
Existing solutions
Most online results indicate that it's something to do with the JVM default heap size and that it can be fixed by setting the appropriate environmental variables.
However, I would want the Ant scripts to run on any computer and not to depend on the environmental variables.
Is there a way to configure these settings in the Ant scripts or the
POM file?
EDIT
The install-provider task (http://maven.apache.org/ant-tasks/examples/install-deploy.html) seems to work for some people. I keep getting download errors when I use it.
Answer
It turns out that I'm not getting the Java heap error when I run my Maven Ant task on a different machine (which probably has more memory allocated to the JVM heap). Hence, I haven't attempted the solution mentioned by #Attila, though it seems to be going in the right direction.

Once ant is running, you cannot change the heap size of the JVM runing ant. So your only option is to run the task that comsumes a large amount of memory in a separate JVM, specifying enough heap space. Note this relies on the task allowing you to fork a new JVM to execute the task
Update: I could not find a way to specify to fork the maven (deploy) task, but this page specifies how you can define a macro to run maven using the java task (note that this relies on maven beeing installed and properly configured on the machine) (see the "Using the Java Task" section)

please try to increase VM memory, eg.: -Xmx512m
if you are using ANT, you can add it to the ANT_OPTS environment variable: ANT_OPTS="-Xmx512m"

Related

How to solve the problem with docker run while running image of Spring Boot App

I am new at Docker and trying to build and run my own container with Spring Boot Application. It runs on Kotlin and Gradle.
I have built the image with simply this command, provided by gradle with spring boot plugin (id("org.springframework.boot") version "2.7.0-SNAPSHOT")
gradlew bootBuildImage
As a result i am getting this. Here are the logs: https://pastebin.com/xMW82vcw
The problem is, while trying to run my built image i am getting this error.
C:\projects\monetka-app>docker run docker.io/library/monetka-app:0.0.1-SNAPSHOT
Setting Active Processor Count to 6
unable to determine class count
unable to walk /workspace
unable to open ZIP /workspace/META-INF/licenses/client-2.1.jar
read /workspace/META-INF/licenses/client-2.1.jar: is a directory
ERROR: failed to launch: exec.d: failed to execute exec.d file at path '/layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/memory-calculator': exit status 1
Here are the docker images i have locally
in docker desktop.
My gradle version is 7.4.1, and JDK in use is 17.
When you run gradlew bootBuildImage, you're using Cloud-Native buildpacks to generate the image. This is a bug in a tool installed by the buildpack.
The Java Cloud-Native buildpack will install a tool called memory-calculator. This tool runs prior to your application starting up and sets up all the JVM memory flags that are required to keep the JVM from going past the defined memory limit you set. For example, if you set the memory limit of your container to be 1G, the memory calculator will adjust settings like -Xmx accordingly.
To do this, the memory calculator needs to know how many class files you have in your application, so it searches for them. This process is failing because it sees something with an extension of .jar and so it's trying to read the number of class files in that JAR, however, what it's seeing META-INF/licenses/client-2.1.jar isn't actually a JAR. It's a directory.
I opened a bug report for you here: https://github.com/paketo-buildpacks/libjvm/issues/160
If you are able to remove the file META-INF/licenses/client-2.1.jar (or change so it doesn't have a .jar extension) you should be able to work around this until we can resolve the issue.

Gradle multi-project parallel build consumes 100% of CPU time

System info
Software info
OS:
Java: OpenJDK 12.0.2
Gradle: 5.6.2
The issue
Building Gradle multi-project with parallel builds enabled consumes almost all the CPU time. PC is not interactable during the build process
Steps to reproduce
1. git clone --recursive https://github.com/vividus-framework/vividus.git
2. cd vividus
3. ./gradlew build
In your gradle.properties file (or GRADLE_OPTS environment variable), try setting org.gradle.priority=low. On my machine it has a noticeable effect with parallel enabled, but I've also heard from some of my co-workers with older machines that this setting didn't help them too much.
You can also experiment with setting org.gradle.workers.max. It defaults to the number of CPU processors. Maybe set it to the number of logical processors minus one.
If it still stops you from interacting with your computer during the build, you should probably just disable parallel execution and let Gradle work on a single processor.

Run application via gradlew with -Xmx and -Xms

I have an application. I run it via
gradlew run-app
Or debug
gradlew debug-app
It works. How do I pass '-Xmx' argument into the application which I run (debug)?
Is it possible to do so without edditing build.gradle file?
I found this
Gradle unknown command-line option '-X'
I get a similar error when I try
gradlew debug-app -Xmx2000m
Error
FAILURE: Build failed with an exception.
* What went wrong:
Problem configuring task :debug-app from command line.
> Unknown command-line option '-X'.
I tried to create a file gradle.properties in GRADLE_USER_HOME directory (by default, it is USER_HOME/.gradle).
org.gradle.jvmargs=-XX\:MaxHeapSize\=4256m -Xmx4256m -Xms2000m
I also tried to org.gradle.jvmargs=-Xmx2000m in project folder gradle.properties.
And even then when I run an application, I see Commited Memory size is < 520 MiB
And this is when I run it as a normal Java App
In the second case, when I run the application as a normal Java app with -Xms, -Xmx, Commited Memory size is about 3.5 GiB because I passed -Xmx4512m -Xms2512m parameters.
Add this in your gradle.properties file :
org.gradle.jvmargs=-Xmx2000m
From here
org.gradle.jvmargs
Specifies the jvmargs used for the daemon process. The setting is
particularly useful for tweaking memory settings. At the moment the
default settings are pretty generous with regards to memory.
edit : my answer what about the gradle daemon jvm, not the app jvm. You have to use the jvmArgs property
The extra arguments to use to launch the JVM for the process. Does not
include system properties and the minimum/maximum heap size.
Firstly, thanks #ToYonos for leading me to the right direction.
Secondly, I found the solution here https://stackoverflow.com/a/9648945/4587961.
I ran my app from command line.
set GRADLE_OPTS=-Xms1724m -Xmx5048m
gradlew debug-app
Note, CMD Windows command SET works locally, so if you close your terminal, GRADLE_OPTS will not be set. For Linux, you can use
export GRADLE_OPTS=WHATEVER
This is what I wanted to achieve.
Using application plugin one can use applicationDefaultJvmArgs property
apply plugin: 'application'
applicationDefaultJvmArgs = ["-Xms1024m", "-Xmx2048m"]
The arguments will be applied to run task and to start script of your application
more info
In my case Invalidate cache and restart the android studio(which is automatically restarted) then the error will be gone after restarting the android studio
then

Gradle - set specific JAVA_HOME for a specific project

Due to different servers running different JVM version. I would like to set a specific project to specific JDK version. I'm thinking may be setting JAVA_HOME with a task which compilation depends on it, but I'm not sure how to code it yet. But then there may be a simple setting I can do in build.gradle for that!?
I think you are after sourceCompatibilityand targetCompatibility. Settings those on a project has - as far as compilation is concerned - the same effect than -source and -target parameters to javac. If you need different settings for different compile tasks in one project, even that would be possible.

How to set Java home path during building Android gradle file via command line?

I want specify the Java home path during building my Android gradle via command line; for example,
gradle build -d path of jdk
Is it possible?
According to gradle documentation:
The following properties can be used to configure the Gradle build
environment:
...
org.gradle.java.home Specifies the Java home for the Gradle build
process. The value can be set to either a jdk or jre location,
however, depending on what your build does, jdk is safer. A reasonable
default is used if the setting is unspecified.
org.gradle.jvmargs Specifies the jvmargs used for the daemon process.
The setting is particularly useful for tweaking memory settings. At
the moment the default settings are pretty generous with regards to
memory.
In other words, you can do it simply by running
gradle build -Dorg.gradle.java.home=<java home path>
Depending on what you want to accomplish, one of the following should work.
As Amnon Shochot suggested, set the -Dorg.gradle.java.home flag. This is probably preferable in most cases.
If you want to have use a particular JDK throughout, set the JAVA_HOME variable appropriately before executing gradle.
$ export JAVA_HOME=/usr/local/specialJava/
$ gradle build
If you don't want to change the environment, try adding the below to your build.gradle script. It should affect only the compiler used to compile Java code, nothing else. So Gradle doesn't run inside this particular JDK, but it will use it for compiling.
tasks.withType(JavaCompile) {
options.fork = true
options.forkOptions.executable = "/usr/local/specialJava/bin/javac"
}
(Last option stolen from here)

Resources