Skip to content

Commit bbfb356

Browse files
committed
Adding java gurobi multi excel file example
1 parent 77e8312 commit bbfb356

12 files changed

Lines changed: 790 additions & 0 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
2+
// README at: https://github.com/devcontainers/templates/tree/main/src/go
3+
{
4+
"name": "Java",
5+
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6+
"image": "ghcr.io/nextmv-io/runtime/java:latest",
7+
"features": {
8+
"ghcr.io/devcontainers/features/java:1": {
9+
"installMaven": "true",
10+
"jdkDistro": "tem",
11+
"version": "21"
12+
}
13+
},
14+
"workspaceMount": "source=${localWorkspaceFolder}/.,target=/app,type=bind",
15+
"workspaceFolder": "/app",
16+
"mounts": [
17+
"source=${localEnv:HOME}${localEnv:USERPROFILE}/gurobi.lic,target=/root/gurobi.lic,type=bind,consistency=cached"
18+
],
19+
"containerEnv": {
20+
"GRB_LICENSE_FILE": "/root/gurobi.lic"
21+
}
22+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
gurobi.lic
2+
.vscode/
3+
main.jar
4+
target/
5+
*.xlsx
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Nextmv Java Gurobi Knapsack
2+
3+
Example for running a Java `Maven` application on the Nextmv Platform using the
4+
Gurobi solver. We solve a knapsack Mixed Integer Programming problem.
5+
6+
1. Setup license:
7+
1. **Local**:
8+
- You can simply place the `gurobi.lic` file in your _home directory_
9+
(like Gurobi expects it). If you are using the dev container, it will be
10+
mounted inside of the container for you.
11+
1. **Platform**: Don't forget to also define the license file as a
12+
[secret][secret] in your Nextmv Application as well. This can be easily
13+
done via [console].
14+
- Define a file secret with the name `gurobi.lic` and the content of
15+
your license file.
16+
- Define an environment variable secret with the name `GRB_LICENSE_FILE`
17+
and the value `./gurobi.lic` to point Gurobi to the license file.
18+
1. Generate a `main.jar`.
19+
20+
```bash
21+
mvn package
22+
```
23+
24+
1. Run the app.
25+
26+
```bash
27+
java -jar main.jar --input input.json
28+
```
29+
30+
1. If above steps were successful, you can push the app to the Nextmv Platform.
31+
E.g., using the [Nextmv CLI][install-cli]:
32+
33+
```bash
34+
nextmv push --app-id <your-app-id>
35+
```
36+
37+
## Mirror running on Nextmv Cloud locally
38+
39+
Docker needs to be installed.
40+
41+
To run the application in the same Docker image as the one used on Nextmv
42+
Cloud, you can use the following command:
43+
44+
```bash
45+
mvn package && cat input.json | docker run -i --rm \
46+
-v $(pwd):/app ghcr.io/nextmv-io/runtime/java:latest \
47+
java -jar /app/main.jar
48+
```
49+
50+
You can also debug the application by running it in a Dev Container. This
51+
workspace recommends to install the Dev Container extension for VSCode. If you
52+
have the extension installed, you can open the workspace in a container by using
53+
the command `Dev Containers: Reopen in Container`.
54+
55+
## Next steps
56+
57+
- Open `src/main/java/com/nextmv/example/Main.java` and modify the model.
58+
- Visit our [docs][docs] and [blog][blog]. Need more assistance?
59+
[Contact][contact] us!
60+
61+
[docs]: https://docs.nextmv.io
62+
[console]: https://cloud.nextmv.io
63+
[secret]: https://www.nextmv.io/docs/using-nextmv/reference/secret-collections
64+
[install-cli]: https://docs.nextmv.io/docs/using-nextmv/setup/install#nextmv-cli
65+
[blog]: https://www.nextmv.io/blog
66+
[contact]: https://www.nextmv.io/contact
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# This manifest holds the information the app needs to run on the Nextmv Cloud.
2+
type: java
3+
runtime: ghcr.io/nextmv-io/runtime/java:latest
4+
5+
# Directives to compile a binary from the app.
6+
pre-push: mvn package
7+
8+
# List all files/directories that should be included in the app. Globbing
9+
# (e.g.: configs/*.json) is supported.
10+
files:
11+
- main.jar
6.21 KB
Binary file not shown.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"folders": [
3+
{
4+
"path": "."
5+
}
6+
],
7+
"launch": {
8+
"configurations": [
9+
{
10+
"type": "java",
11+
"name": "Main",
12+
"request": "launch",
13+
"mainClass": "com.nextmv.example.Main",
14+
"projectName": "GurobiJava",
15+
"args": ["--input", "input.json", "--output", "output.json"]
16+
}
17+
]
18+
},
19+
"extensions": {
20+
"recommendations": ["ms-vscode-remote.remote-containers"]
21+
},
22+
"settings": {
23+
"java.configuration.updateBuildConfiguration": "interactive"
24+
}
25+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<groupId>com.nextmv.example</groupId>
7+
<artifactId>GurobiJava</artifactId>
8+
<version>1.0.0</version>
9+
<packaging>jar</packaging>
10+
11+
<name>${project.groupId}:${project.artifactId}</name>
12+
<description>Sample using Gurobi via Java.</description>
13+
<url>https://github.com/nextmv-io</url>
14+
15+
<licenses>
16+
<license>
17+
<name>The Apache License, Version 2.0</name>
18+
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
19+
</license>
20+
</licenses>
21+
22+
<developers>
23+
<developer>
24+
<name>Nextmv Team</name>
25+
<email>support@nextmv.io</email>
26+
<organization>Nextmv</organization>
27+
<organizationUrl>https://www.nextmv.io</organizationUrl>
28+
</developer>
29+
</developers>
30+
31+
<properties>
32+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
33+
<exec.mainClass>com.nextmv.example.Main</exec.mainClass>
34+
<maven.compiler.source>21</maven.compiler.source>
35+
<maven.compiler.target>21</maven.compiler.target>
36+
</properties>
37+
38+
<dependencies>
39+
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
40+
<dependency>
41+
<groupId>org.apache.logging.log4j</groupId>
42+
<artifactId>log4j-api</artifactId>
43+
<version>2.25.0</version>
44+
</dependency>
45+
<!-- https://mvnrepository.com/artifact/com.gurobi/gurobi -->
46+
<dependency>
47+
<groupId>com.gurobi</groupId>
48+
<artifactId>gurobi</artifactId>
49+
<version>12.0.2</version>
50+
<type>jar</type>
51+
<scope>compile</scope>
52+
</dependency>
53+
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
54+
<dependency>
55+
<groupId>com.google.code.gson</groupId>
56+
<artifactId>gson</artifactId>
57+
<version>2.13.1</version>
58+
</dependency>
59+
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
60+
<dependency>
61+
<groupId>org.apache.poi</groupId>
62+
<artifactId>poi</artifactId>
63+
<version>5.4.1</version>
64+
</dependency>
65+
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
66+
<dependency>
67+
<groupId>org.apache.poi</groupId>
68+
<artifactId>poi-ooxml</artifactId>
69+
<version>5.4.1</version>
70+
</dependency>
71+
</dependencies>
72+
73+
<build>
74+
<plugins>
75+
<plugin>
76+
<groupId>org.apache.maven.plugins</groupId>
77+
<artifactId>maven-source-plugin</artifactId>
78+
<version>3.2.0</version>
79+
<executions>
80+
<execution>
81+
<id>attach-sources</id>
82+
<goals>
83+
<goal>jar-no-fork</goal>
84+
</goals>
85+
</execution>
86+
</executions>
87+
</plugin>
88+
<plugin>
89+
<groupId>org.apache.maven.plugins</groupId>
90+
<artifactId>maven-gpg-plugin</artifactId>
91+
<version>1.6</version>
92+
<executions>
93+
<execution>
94+
<id>sign-artifacts</id>
95+
<phase>verify</phase>
96+
<goals>
97+
<goal>sign</goal>
98+
</goals>
99+
</execution>
100+
</executions>
101+
</plugin>
102+
<plugin>
103+
<artifactId>maven-assembly-plugin</artifactId>
104+
<executions>
105+
<execution>
106+
<phase>package</phase>
107+
<goals>
108+
<goal>single</goal>
109+
</goals>
110+
</execution>
111+
</executions>
112+
<configuration>
113+
<archive>
114+
<manifest>
115+
<mainClass>com.nextmv.example.Main</mainClass>
116+
</manifest>
117+
</archive>
118+
<descriptorRefs>
119+
<descriptorRef>jar-with-dependencies</descriptorRef>
120+
</descriptorRefs>
121+
<outputDirectory>.</outputDirectory>
122+
<finalName>main</finalName>
123+
<appendAssemblyId>false</appendAssemblyId>
124+
</configuration>
125+
</plugin>
126+
</plugins>
127+
</build>
128+
</project>
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.nextmv.example;
2+
3+
import org.apache.poi.ss.usermodel.*;
4+
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
5+
import java.io.FileInputStream;
6+
import java.io.IOException;
7+
import java.util.ArrayList;
8+
import java.util.Iterator;
9+
import java.util.List;
10+
11+
public class ExcelReader {
12+
13+
public Input readExcelFile(String filePath) throws IOException {
14+
FileInputStream file = new FileInputStream(filePath);
15+
Workbook workbook = new XSSFWorkbook(file);
16+
17+
List<Item> items = readItemsSheet(workbook);
18+
List<Knapsack> knapsacks = readKnapsacksSheet(workbook);
19+
20+
workbook.close();
21+
file.close();
22+
23+
return new Input(items, knapsacks);
24+
}
25+
26+
private List<Item> readItemsSheet(Workbook workbook) {
27+
List<Item> items = new ArrayList<>();
28+
Sheet sheet = workbook.getSheet("items");
29+
30+
Iterator<Row> rowIterator = sheet.iterator();
31+
// Skip header row
32+
if (rowIterator.hasNext()) {
33+
rowIterator.next();
34+
}
35+
36+
while (rowIterator.hasNext()) {
37+
Row row = rowIterator.next();
38+
String id = row.getCell(0).getStringCellValue();
39+
double value = row.getCell(1).getNumericCellValue();
40+
double weight = row.getCell(2).getNumericCellValue();
41+
42+
items.add(new Item(id, value, weight));
43+
}
44+
45+
return items;
46+
}
47+
48+
private List<Knapsack> readKnapsacksSheet(Workbook workbook) {
49+
List<Knapsack> knapsacks = new ArrayList<>();
50+
Sheet sheet = workbook.getSheet("knapsacks");
51+
52+
Iterator<Row> rowIterator = sheet.iterator();
53+
// Skip header row
54+
if (rowIterator.hasNext()) {
55+
rowIterator.next();
56+
}
57+
58+
while (rowIterator.hasNext()) {
59+
Row row = rowIterator.next();
60+
String id = row.getCell(0).getStringCellValue();
61+
double capacity = row.getCell(1).getNumericCellValue();
62+
63+
knapsacks.add(new Knapsack(id, capacity));
64+
}
65+
66+
return knapsacks;
67+
}
68+
}
69+
70+
class Input {
71+
private List<Item> items;
72+
private List<Knapsack> knapsacks;
73+
74+
public Input(List<Item> items, List<Knapsack> knapsacks) {
75+
this.items = items;
76+
this.knapsacks = knapsacks;
77+
}
78+
79+
public List<Item> getItems() {
80+
return items;
81+
}
82+
83+
public List<Knapsack> getKnapsacks() {
84+
return knapsacks;
85+
}
86+
}
87+
88+
class Item {
89+
private String id;
90+
private double value;
91+
private double weight;
92+
93+
public Item(String id, double value, double weight) {
94+
this.id = id;
95+
this.value = value;
96+
this.weight = weight;
97+
}
98+
99+
public String getId() {
100+
return id;
101+
}
102+
103+
public double getValue() {
104+
return value;
105+
}
106+
107+
public double getWeight() {
108+
return weight;
109+
}
110+
}
111+
112+
class Knapsack {
113+
private String id;
114+
private double capacity;
115+
116+
public Knapsack(String id, double capacity) {
117+
this.id = id;
118+
this.capacity = capacity;
119+
}
120+
121+
public String getId() {
122+
return id;
123+
}
124+
125+
public double getCapacity() {
126+
return capacity;
127+
}
128+
}

0 commit comments

Comments
 (0)