Skip to content

Commit c94c05d

Browse files
committed
add java code executor
1 parent 079cf47 commit c94c05d

File tree

18 files changed

+424
-18
lines changed

18 files changed

+424
-18
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM maven:3.9.9-eclipse-temurin-21 AS build
2+
3+
ADD ./app/pom.xml /app/pom.xml
4+
ADD ./app/Main.java /app/src/main/java/Main.java
5+
6+
WORKDIR /app
7+
8+
RUN mvn compile exec:java
9+
10+
FROM maven:3.9.9-eclipse-temurin-21
11+
COPY --from=build /root/.m2 /root/.m2
12+
13+
WORKDIR /app
14+
ADD ./app/pom.xml /app/pom.xml
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
public class Main {
2+
3+
public static void main(String[] args) {
4+
System.out.println("Hello World!");
5+
}
6+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.javaaidev.llmcodeexecutor</groupId>
8+
<artifactId>generate-app</artifactId>
9+
<version>0.1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<java.version>21</java.version>
13+
<maven.compiler.source>21</maven.compiler.source>
14+
<maven.compiler.target>21</maven.compiler.target>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
</properties>
17+
18+
<dependencies>
19+
20+
<dependency>
21+
<groupId>com.google.guava</groupId>
22+
<artifactId>guava</artifactId>
23+
<version>33.4.6-jre</version>
24+
</dependency>
25+
26+
<dependency>
27+
<groupId>org.apache.commons</groupId>
28+
<artifactId>commons-lang3</artifactId>
29+
<version>3.17.0</version>
30+
</dependency>
31+
32+
<dependency>
33+
<groupId>com.fasterxml.jackson.core</groupId>
34+
<artifactId>jackson-databind</artifactId>
35+
<version>2.18.3</version>
36+
</dependency>
37+
38+
<dependency>
39+
<groupId>com.squareup.okhttp3</groupId>
40+
<artifactId>okhttp</artifactId>
41+
<version>4.12.0</version>
42+
</dependency>
43+
44+
</dependencies>
45+
46+
<build>
47+
<plugins>
48+
<plugin>
49+
<groupId>org.codehaus.mojo</groupId>
50+
<artifactId>exec-maven-plugin</artifactId>
51+
<version>3.5.0</version>
52+
<executions>
53+
<execution>
54+
<goals>
55+
<goal>java</goal>
56+
</goals>
57+
</execution>
58+
</executions>
59+
<configuration>
60+
<mainClass>Main</mainClass>
61+
</configuration>
62+
</plugin>
63+
</plugins>
64+
</build>
65+
66+
</project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"javaVersion": "21",
3+
"dependencies": [
4+
{
5+
"groupId": "com.google.guava",
6+
"artifactId": "guava",
7+
"artifactVersion": "33.4.6-jre"
8+
},
9+
{
10+
"groupId": "org.apache.commons",
11+
"artifactId": "commons-lang3",
12+
"artifactVersion": "3.17.0"
13+
},
14+
{
15+
"groupId": "com.fasterxml.jackson.core",
16+
"artifactId": "jackson-databind",
17+
"artifactVersion": "2.18.3"
18+
},
19+
{
20+
"groupId": "com.squareup.okhttp3",
21+
"artifactId": "okhttp",
22+
"artifactVersion": "4.12.0"
23+
}
24+
]
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.javaaidev.llmcodeexecutor.containerimagegenerator
2+
3+
import com.github.jknack.handlebars.EscapingStrategy
4+
import com.github.jknack.handlebars.Handlebars
5+
import com.github.jknack.handlebars.io.ClassPathTemplateLoader
6+
import org.slf4j.LoggerFactory
7+
import java.nio.file.Files
8+
import java.nio.file.Path
9+
import java.util.function.Supplier
10+
import kotlin.io.path.exists
11+
12+
data class GeneratedFile(
13+
val templateName: String,
14+
val dir: Path,
15+
val overwrite: Boolean = true,
16+
val fileNameSupplier: Supplier<String> = Supplier<String> { templateName },
17+
)
18+
19+
object TemplateHelper {
20+
private val logger = LoggerFactory.getLogger(TemplateHelper::class.java)
21+
22+
fun writeFiles(templatePrefix: String, files: List<GeneratedFile>, templateContext: Any) {
23+
val loader = ClassPathTemplateLoader()
24+
loader.prefix = templatePrefix
25+
val handlebars = Handlebars(loader).with(EscapingStrategy.NOOP)
26+
27+
files.forEach { file ->
28+
val outputFile = file.dir.resolve(file.fileNameSupplier.get())
29+
if (outputFile.exists() && !file.overwrite) {
30+
logger.info("Skip generation of file {}", outputFile)
31+
return@forEach
32+
}
33+
val template = handlebars.compile(file.templateName)
34+
template.apply(templateContext).run {
35+
logger.info("Created file {}", outputFile.toAbsolutePath().normalize())
36+
Files.writeString(outputFile, this)
37+
}
38+
}
39+
}
40+
}

container-image-generator/src/main/kotlin/com/javaaidev/llmcodeexecutor/containerimagegenerator/ContainerImageGeneratorCli.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.javaaidev.llmcodeexecutor.containerimagegenerator
22

3+
import com.javaaidev.llmcodeexecutor.containerimagegenerator.java.JavaContainerImageGeneratorCommand
34
import com.javaaidev.llmcodeexecutor.containerimagegenerator.python.PythonContainerImageGeneratorCommand
45
import picocli.CommandLine
56
import picocli.CommandLine.Command
@@ -27,6 +28,7 @@ class ReusableOptions {
2728
scope = CommandLine.ScopeType.INHERIT,
2829
subcommands = [
2930
PythonContainerImageGeneratorCommand::class,
31+
JavaContainerImageGeneratorCommand::class,
3032
],
3133
)
3234
class ContainerImageGeneratorCli
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.javaaidev.llmcodeexecutor.containerimagegenerator.java
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper
4+
import com.fasterxml.jackson.module.kotlin.KotlinModule
5+
import com.javaaidev.llmcodeexecutor.containerimagegenerator.GeneratedFile
6+
import com.javaaidev.llmcodeexecutor.containerimagegenerator.ReusableOptions
7+
import com.javaaidev.llmcodeexecutor.containerimagegenerator.TemplateHelper
8+
import org.slf4j.LoggerFactory
9+
import picocli.CommandLine
10+
import picocli.CommandLine.Command
11+
import java.nio.file.Files
12+
import java.nio.file.Path
13+
import java.util.concurrent.Callable
14+
15+
object JavaContainerImageGenerator {
16+
private val logger = LoggerFactory.getLogger(JavaContainerImageGenerator::class.java)
17+
18+
fun generate(profile: JavaProfile, outputDir: Path) {
19+
logger.info("Generate Java container image")
20+
val appDir = outputDir.resolve("app")
21+
Files.createDirectories(appDir)
22+
val files = listOf(
23+
GeneratedFile("pom.xml", appDir),
24+
GeneratedFile("Main.java", appDir),
25+
GeneratedFile("Dockerfile", outputDir),
26+
)
27+
28+
TemplateHelper.writeFiles("/templates/java", files, profile)
29+
}
30+
}
31+
32+
@Command(name = "java", description = ["Generate Java container image"])
33+
class JavaContainerImageGeneratorCommand : Callable<Int> {
34+
@CommandLine.Mixin
35+
lateinit var options: ReusableOptions
36+
37+
private val objectMapper = ObjectMapper().registerModules(KotlinModule.Builder().build())
38+
39+
override fun call(): Int {
40+
val profile = objectMapper.readValue(options.inputProfile, JavaProfile::class.java)
41+
JavaContainerImageGenerator.generate(profile, options.outputDir.toPath())
42+
return 0
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.javaaidev.llmcodeexecutor.containerimagegenerator.java
2+
3+
data class JavaProfile(val javaVersion: String, val dependencies: List<MavenDependency>)
4+
5+
data class MavenDependency(
6+
val groupId: String,
7+
val artifactId: String,
8+
val artifactVersion: String
9+
)

container-image-generator/src/main/kotlin/com/javaaidev/llmcodeexecutor/containerimagegenerator/python/PythonContainerImageGenerator.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,16 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule
55
import com.github.jknack.handlebars.EscapingStrategy
66
import com.github.jknack.handlebars.Handlebars
77
import com.github.jknack.handlebars.io.ClassPathTemplateLoader
8+
import com.javaaidev.llmcodeexecutor.containerimagegenerator.GeneratedFile
89
import com.javaaidev.llmcodeexecutor.containerimagegenerator.ReusableOptions
910
import org.slf4j.LoggerFactory
1011
import picocli.CommandLine
1112
import picocli.CommandLine.Command
1213
import java.nio.file.Files
1314
import java.nio.file.Path
1415
import java.util.concurrent.Callable
15-
import java.util.function.Supplier
1616
import kotlin.io.path.exists
1717

18-
data class GeneratedFile(
19-
val templateName: String,
20-
val dir: Path,
21-
val overwrite: Boolean = true,
22-
val fileNameSupplier: Supplier<String>,
23-
)
24-
2518
object PythonContainerImageGenerator {
2619
private val handlebars: Handlebars
2720
private val logger = LoggerFactory.getLogger(PythonContainerImageGenerator::class.java)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM maven:3.9.9-eclipse-temurin-{{javaVersion}} AS build
2+
3+
ADD ./app/pom.xml /app/pom.xml
4+
ADD ./app/Main.java /app/src/main/java/Main.java
5+
6+
WORKDIR /app
7+
8+
RUN mvn compile exec:java
9+
10+
FROM maven:3.9.9-eclipse-temurin-{{javaVersion}}
11+
COPY --from=build /root/.m2 /root/.m2
12+
13+
WORKDIR /app
14+
ADD ./app/pom.xml /app/pom.xml
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
public class Main {
2+
3+
public static void main(String[] args) {
4+
System.out.println("Hello World!");
5+
}
6+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.javaaidev.llmcodeexecutor</groupId>
8+
<artifactId>generate-app</artifactId>
9+
<version>0.1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<java.version>{{javaVersion}}</java.version>
13+
<maven.compiler.source>{{javaVersion}}</maven.compiler.source>
14+
<maven.compiler.target>{{javaVersion}}</maven.compiler.target>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
</properties>
17+
18+
<dependencies>
19+
{{#dependencies}}
20+
<dependency>
21+
<groupId>{{groupId}}</groupId>
22+
<artifactId>{{artifactId}}</artifactId>
23+
<version>{{artifactVersion}}</version>
24+
</dependency>
25+
{{/dependencies}}
26+
</dependencies>
27+
28+
<build>
29+
<plugins>
30+
<plugin>
31+
<groupId>org.codehaus.mojo</groupId>
32+
<artifactId>exec-maven-plugin</artifactId>
33+
<version>3.5.0</version>
34+
<executions>
35+
<execution>
36+
<goals>
37+
<goal>java</goal>
38+
</goals>
39+
</execution>
40+
</executions>
41+
<configuration>
42+
<mainClass>Main</mainClass>
43+
</configuration>
44+
</plugin>
45+
</plugins>
46+
</build>
47+
48+
</project>

0 commit comments

Comments
 (0)