âšī¸ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://mccue.dev/pages/1-11-24-cli-flow |
| Last Crawled | 2026-04-10 03:33:08 (1 day ago) |
| First Indexed | 2024-01-12 07:57:32 (2 years ago) |
| HTTP Status Code | 200 |
| Meta Title | The Java Command Line Workflow |
| Meta Description | null |
| Meta Canonical | null |
| Boilerpipe Text | by:
Ethan McCue
A while ago, I released a draft of the
jresolve
command line tool. Its function is to take a set of root dependency declarations and resolve the full set of transitive dependencies.
I'm happy with the API, but there are some things to fix up.
But I think
jresolve
's existence, and why I bothered to make it, only makes sense as a part of a larger story. This is an attempt to tell it.
The Problem
We all use Maven or Gradle. There are other up-and-coming build tools like
bld
and some
Ant
holdovers from the 2000s, but if you threw darts at Java codebases that is what you would hit.
This is a good state of affairs in many ways, but there are downsides.
The specific downside I want to focus on is how it affects the way people learn Java. What follows are my own opinions and perception.
Step 1.
When people learn how to code, typically they start with a "Hello, world" program.
In the past, this part involved hand-waving away
public static void main(String[] args)
. In some future release of Java
it will be simpler
. That's great. I'll talk about how can affect curriculums at some point.
But from a tooling perspective, this step is a choice between having them run
java Main.java
on the command line and having them click the "Big Green Run Button" in whatever text editor they installed or online platform they signed up for.
Step 2.
You can actually go pretty far into the language without leaving a single file, but at some point a student needs to have more than one file in their projects.
To do this, you again have a (non-exclusive) choice of how to approach it. Either the command line or the Big Green Run Button.
If you take the command line route, it
will be
still
java Main.java
, followed by
java src/Main.java
after you guide them to keep their code in a folder.
Green button is the green button.
Step 3.
Because it will be relevant to things to come, you at some point want to explain that Java code can be compiled ahead of time to
.class
files. You could point to the directory where the B.G.R.B. put the class files, or you could explain what
javac
is and how to use it. For that you would land on something like this.
javac --source-path ./src -d classes src/Main.java
java --class-path classes Main
So you would have been able to introduce
javac
, the concept of ahead of time compilation,
.class
files, and the
--class-path
.
Step 4.
Once they've made an app
the next thing they'll want
is to package it up into a jar.
In the đĸ world, you show them a menu in their editor and what buttons to click.
In the CLI, it's a chance to show them how to use the
jar
tool.
jar --create --file app.jar --main-class Main -C classes .
Step 5.
This is where things get tricky, because once they know how to build an app it won't be long before they want to make something that requires a dependency.
And it is this step where things fall apart.
If you are lucky, the dependency they need has no transitive dependencies. You show them how to download a
.jar
file, how to add it to the IDE or where to put it on the
--class-path
, and warn them that they won't be able to get way with that forever.
If you aren't, you need Maven or Gradle. That is by far the easiest way to make sure they get their dependencies.
It is also easy to justify. Chances are any Java job would use one of those.
One problem is that because Maven and Gradle also take over compiling the code, you invalidate their investment in learning how to use
javac
and
jar
. They won't be using either of those from now on.
Another is that both are going to throw a lot in their face. Either an entirely new programming language with Gradle or a relatively beefy
pom.xml
with Maven.
This is what a "blank" Maven gives you in IntelliJ. It's not
horrible
, but it does have some
public static void main(String[] args)
-like properties.
<?xml
version=
"1.0"
encoding=
"UTF-8"
?>
<
project
xmlns
=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<
modelVersion
>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>untitled92</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
You could also use something like
jbang
, which automatically downloads dependencies declared as comments in the code. But this stops being viable if you want those dependencies for things other than running the code as a script, unfortunately.
So the point of
jresolve
specifically is to let you stick with the command-line flow and avoid pivoting to build tools until later.
You show them how to use it to get dependencies from the internet as well as how to use those dependencies.
jresolve \
--output-directory libraries \
pkg:maven/de.gurkenlabs/litiengine@0.8.0
javac \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--source-path ./src \
-d classes \
src/Main.java
java \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--class-path classes \
Main
As an aside, while it requires the unpleasant appearance of
ALL-MODULE-PATH
I would argue that showing early that you should put your external dependencies on the
--module-path
is a good thing.
Step 6.
If you took the path enabled by a tool like
jresolve
, the commands you are asking folks to run likely are getting pretty hard to remember.
It is a good time to introduce some "command runner" mechanism. Some way so they only have to say
compile
instead of a long
javac
incantation.
For this purpose, I have a liking for
just
, but shell scripts, makefiles, etc. are all valid.
help:
just --list
clean:
rm -rf classes
rm -rf libraries
install:
rm -rf libraries
jresolve \
--output-directory libraries \
pkg:maven/de.gurkenlabs/litiengine@0.8.0
compile:
rm -rf classes
javac \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--source-path ./src \
-d classes \
src/Main.java
run:
java \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--class-path classes \
Main
Now that they can do something spiritually like
just compile
, commands no longer need to be produced from memory every time they want to do things with their code.
It also instills the notion that software projects are generally built by a set of named and repeatable processes.
And if you haven't or its just time for a refresher, you can use this as an opportunity to go a little deeper into the command line and explain tools like
cd
and
rm
.
Step 7.
Now that they know how to use dependencies and can run somewhat involved processes in the CLI, you can show them how to package their code to share with someone who doesn't have Java.
If they've made games and other such gui things, then you can show them
jpackage
. Have them make a
jar
with their classes and show them the flags to include their dependencies and make an installer.
If you've kept more of a server-y focus, maybe you'd just show them how to copy files to a remote machine, maybe you'd go through something like docker and show them the commands to build images.
But at this point they have some idea of how to "ship" their code.
Step 8.
Now that they have all the mechanisms to deliver code from concept to product, they are going to start making big projects.
At least some students will have an idea for a game or a website or similar they're going to invest a lot of time in, but also the assignments you are giving will probably require more structure. A thing I've seen in a lot of curriculums is to have everyone do the
M
part of an
MVC
type assignment and swap
M
s with another group and write the
V
and
C
using that.
As such, it is as good a time as any to introduce modules.
The path of least resistance would be to introduce the multi-module format that
javac
understands. I.E you have a top level directory for each module that has the module's name.
some.mod/
src/
module-info.java
some/
mod/
...
other.mod/
src/
module-info.java
other/
mod/
...
javac \
-d compiled \
--module-path libraries \
--module-source-path "./*/src" \
--module some.mod,other.mod
That will require talking about visibility and packages, so it's a good point to also start talking about higher level concepts like encapsulation and library contracts.
Step 9.
Maybe this can be done a bit sooner, but you definitely need to show those goobers how to write unit tests now.
The best way to do this is to show them how to use
junit
.
java --module-path libraries:compiled \
--add-modules ALL-MODULE-PATH \
org.junit.platform.console.ConsoleLauncher execute --scan-modules
Maybe there can be a
junit
executable ready via some mechanism, but either way all the mechanics of even this relatively verbose incantation have been shown.
And this is a great point to introduce the practice of having a separate
test
folder. Also potentially
resources
since tests can use those as a source of test data.
Step 10.
At some point now that they know how to write code, write tests, design modules, etc. It would be a good point to get into library writing. Not everyone will, but some will try their hand.
It's at this point that learning Maven or Gradle probably becomes needed, though I think with a smidgen more tooling that can be delayed. Maybe just something to generate a POM +
jreleaser
would be enough.
Step N.
Then, at some point, they have need for a real build tool. I won't opine on this, but I think some people wouldn't ever reach this step.
They will have already gotten a relatively deep understanding of the underlying tools, naturally come across the concept of a build task, know what a library is and what Maven coordinates are and do, and they will have enough context to know why Maven would choose
src/main/java
as the place to put code.
I think this is a healthier level to engage with build-tools at. Understanding what tasks they automate because you've done those tasks manually.
It also gives a firmer foundation for the more exotic parts of tooling like agents, AppCDS, annotation processors, etc. Build tools aren't always the most intuitive with those.
Conclusion
This might not be appropriate for all curriculums. Sometimes you are in a boot-camp and you just gotta be employable with Spring in 6 months.
But when the goal of an education isn't optimizing time to employment, I think teaching with the command-line first has value. I just think that in order for it to be actually practical, a few more pieces need to be in place.
So that aspiration is what
jresolve
is for. It is what whatever CLI tool I make next will probably be for. That's the vision. Have the JDK be enough, by itself, to get bootstrapped into modern software development. Lower the barrier of entry to be around that of JavaScript and Python.
Tell me what I got wrong in the comments below.
<- Index |
| Markdown | # The Java Command Line Workflow
by: **Ethan McCue**
A while ago, I released a draft of the [jresolve](https://github.com/bowbahdoe/jresolve-cli) command line tool. Its function is to take a set of root dependency declarations and resolve the full set of transitive dependencies.
I'm happy with the API, but there are some things to fix up.
But I think `jresolve`'s existence, and why I bothered to make it, only makes sense as a part of a larger story. This is an attempt to tell it.
## The Problem
We all use Maven or Gradle. There are other up-and-coming build tools like [bld](https://rife2.com/bld) and some [Ant](https://ant.apache.org/) holdovers from the 2000s, but if you threw darts at Java codebases that is what you would hit.
This is a good state of affairs in many ways, but there are downsides.
The specific downside I want to focus on is how it affects the way people learn Java. What follows are my own opinions and perception.
## Step 1.
When people learn how to code, typically they start with a "Hello, world" program.
In the past, this part involved hand-waving away `public static void main(String[] args)`. In some future release of Java [it will be simpler](https://openjdk.org/jeps/445). That's great. I'll talk about how can affect curriculums at some point.
But from a tooling perspective, this step is a choice between having them run `java Main.java` on the command line and having them click the "Big Green Run Button" in whatever text editor they installed or online platform they signed up for.
## Step 2.
You can actually go pretty far into the language without leaving a single file, but at some point a student needs to have more than one file in their projects.
To do this, you again have a (non-exclusive) choice of how to approach it. Either the command line or the Big Green Run Button.
If you take the command line route, it [will be](https://openjdk.org/jeps/458) still `java Main.java`, followed by `java src/Main.java` after you guide them to keep their code in a folder.
Green button is the green button.
## Step 3.
Because it will be relevant to things to come, you at some point want to explain that Java code can be compiled ahead of time to `.class` files. You could point to the directory where the B.G.R.B. put the class files, or you could explain what `javac` is and how to use it. For that you would land on something like this.
```
javac --source-path ./src -d classes src/Main.java
java --class-path classes Main
```
So you would have been able to introduce `javac`, the concept of ahead of time compilation, `.class` files, and the `--class-path`.
## Step 4.
Once they've made an app [the next thing they'll want](https://www.youtube.com/watch?v=WszAwrlS5GM) is to package it up into a jar.
In the đĸ world, you show them a menu in their editor and what buttons to click.
In the CLI, it's a chance to show them how to use the `jar` tool.
```
jar --create --file app.jar --main-class Main -C classes .
```
## Step 5.
This is where things get tricky, because once they know how to build an app it won't be long before they want to make something that requires a dependency.
And it is this step where things fall apart.
If you are lucky, the dependency they need has no transitive dependencies. You show them how to download a `.jar` file, how to add it to the IDE or where to put it on the `--class-path`, and warn them that they won't be able to get way with that forever.
If you aren't, you need Maven or Gradle. That is by far the easiest way to make sure they get their dependencies.
It is also easy to justify. Chances are any Java job would use one of those.
One problem is that because Maven and Gradle also take over compiling the code, you invalidate their investment in learning how to use `javac` and `jar`. They won't be using either of those from now on.
Another is that both are going to throw a lot in their face. Either an entirely new programming language with Gradle or a relatively beefy `pom.xml` with Maven.
This is what a "blank" Maven gives you in IntelliJ. It's not *horrible*, but it does have some `public static void main(String[] args)`\-like properties.
```
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>untitled92</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
```
You could also use something like [`jbang`](https://www.jbang.dev/), which automatically downloads dependencies declared as comments in the code. But this stops being viable if you want those dependencies for things other than running the code as a script, unfortunately.
So the point of `jresolve` specifically is to let you stick with the command-line flow and avoid pivoting to build tools until later.
You show them how to use it to get dependencies from the internet as well as how to use those dependencies.
```
jresolve \
--output-directory libraries \
pkg:maven/de.gurkenlabs/litiengine@0.8.0
javac \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--source-path ./src \
-d classes \
src/Main.java
java \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--class-path classes \
Main
```
As an aside, while it requires the unpleasant appearance of `ALL-MODULE-PATH` I would argue that showing early that you should put your external dependencies on the `--module-path` is a good thing.
## Step 6.
If you took the path enabled by a tool like `jresolve`, the commands you are asking folks to run likely are getting pretty hard to remember.
It is a good time to introduce some "command runner" mechanism. Some way so they only have to say `compile` instead of a long `javac` incantation.
For this purpose, I have a liking for [just](https://github.com/casey/just), but shell scripts, makefiles, etc. are all valid.
```
help:
just --list
clean:
rm -rf classes
rm -rf libraries
install:
rm -rf libraries
jresolve \
--output-directory libraries \
pkg:maven/de.gurkenlabs/litiengine@0.8.0
compile:
rm -rf classes
javac \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--source-path ./src \
-d classes \
src/Main.java
run:
java \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--class-path classes \
Main
```
Now that they can do something spiritually like `just compile`, commands no longer need to be produced from memory every time they want to do things with their code.
It also instills the notion that software projects are generally built by a set of named and repeatable processes.
And if you haven't or its just time for a refresher, you can use this as an opportunity to go a little deeper into the command line and explain tools like `cd` and `rm`.
## Step 7.
Now that they know how to use dependencies and can run somewhat involved processes in the CLI, you can show them how to package their code to share with someone who doesn't have Java.
If they've made games and other such gui things, then you can show them `jpackage`. Have them make a `jar` with their classes and show them the flags to include their dependencies and make an installer.
If you've kept more of a server-y focus, maybe you'd just show them how to copy files to a remote machine, maybe you'd go through something like docker and show them the commands to build images.
But at this point they have some idea of how to "ship" their code.
## Step 8.
Now that they have all the mechanisms to deliver code from concept to product, they are going to start making big projects.
At least some students will have an idea for a game or a website or similar they're going to invest a lot of time in, but also the assignments you are giving will probably require more structure. A thing I've seen in a lot of curriculums is to have everyone do the `M` part of an `MVC` type assignment and swap `M`s with another group and write the `V` and `C` using that.
As such, it is as good a time as any to introduce modules.
The path of least resistance would be to introduce the multi-module format that `javac` understands. I.E you have a top level directory for each module that has the module's name.
```
some.mod/
src/
module-info.java
some/
mod/
...
other.mod/
src/
module-info.java
other/
mod/
...
```
```
javac \
-d compiled \
--module-path libraries \
--module-source-path "./*/src" \
--module some.mod,other.mod
```
That will require talking about visibility and packages, so it's a good point to also start talking about higher level concepts like encapsulation and library contracts.
## Step 9.
Maybe this can be done a bit sooner, but you definitely need to show those goobers how to write unit tests now.
The best way to do this is to show them how to use `junit`.
```
java --module-path libraries:compiled \
--add-modules ALL-MODULE-PATH \
org.junit.platform.console.ConsoleLauncher execute --scan-modules
```
Maybe there can be a `junit` executable ready via some mechanism, but either way all the mechanics of even this relatively verbose incantation have been shown.
And this is a great point to introduce the practice of having a separate `test` folder. Also potentially `resources` since tests can use those as a source of test data.
## Step 10.
At some point now that they know how to write code, write tests, design modules, etc. It would be a good point to get into library writing. Not everyone will, but some will try their hand.
It's at this point that learning Maven or Gradle probably becomes needed, though I think with a smidgen more tooling that can be delayed. Maybe just something to generate a POM + `jreleaser` would be enough.
## Step N.
Then, at some point, they have need for a real build tool. I won't opine on this, but I think some people wouldn't ever reach this step.
They will have already gotten a relatively deep understanding of the underlying tools, naturally come across the concept of a build task, know what a library is and what Maven coordinates are and do, and they will have enough context to know why Maven would choose `src/main/java` as the place to put code.
I think this is a healthier level to engage with build-tools at. Understanding what tasks they automate because you've done those tasks manually.
It also gives a firmer foundation for the more exotic parts of tooling like agents, AppCDS, annotation processors, etc. Build tools aren't always the most intuitive with those.
## Conclusion
This might not be appropriate for all curriculums. Sometimes you are in a boot-camp and you just gotta be employable with Spring in 6 months.
But when the goal of an education isn't optimizing time to employment, I think teaching with the command-line first has value. I just think that in order for it to be actually practical, a few more pieces need to be in place.
So that aspiration is what `jresolve` is for. It is what whatever CLI tool I make next will probably be for. That's the vision. Have the JDK be enough, by itself, to get bootstrapped into modern software development. Lower the barrier of entry to be around that of JavaScript and Python.
***
Tell me what I got wrong in the comments below.
***
#### [\<- Index](https://mccue.dev/) |
| Readable Markdown | by: **Ethan McCue**
A while ago, I released a draft of the [jresolve](https://github.com/bowbahdoe/jresolve-cli) command line tool. Its function is to take a set of root dependency declarations and resolve the full set of transitive dependencies.
I'm happy with the API, but there are some things to fix up.
But I think `jresolve`'s existence, and why I bothered to make it, only makes sense as a part of a larger story. This is an attempt to tell it.
## The Problem
We all use Maven or Gradle. There are other up-and-coming build tools like [bld](https://rife2.com/bld) and some [Ant](https://ant.apache.org/) holdovers from the 2000s, but if you threw darts at Java codebases that is what you would hit.
This is a good state of affairs in many ways, but there are downsides.
The specific downside I want to focus on is how it affects the way people learn Java. What follows are my own opinions and perception.
## Step 1.
When people learn how to code, typically they start with a "Hello, world" program.
In the past, this part involved hand-waving away `public static void main(String[] args)`. In some future release of Java [it will be simpler](https://openjdk.org/jeps/445). That's great. I'll talk about how can affect curriculums at some point.
But from a tooling perspective, this step is a choice between having them run `java Main.java` on the command line and having them click the "Big Green Run Button" in whatever text editor they installed or online platform they signed up for.
## Step 2.
You can actually go pretty far into the language without leaving a single file, but at some point a student needs to have more than one file in their projects.
To do this, you again have a (non-exclusive) choice of how to approach it. Either the command line or the Big Green Run Button.
If you take the command line route, it [will be](https://openjdk.org/jeps/458) still `java Main.java`, followed by `java src/Main.java` after you guide them to keep their code in a folder.
Green button is the green button.
## Step 3.
Because it will be relevant to things to come, you at some point want to explain that Java code can be compiled ahead of time to `.class` files. You could point to the directory where the B.G.R.B. put the class files, or you could explain what `javac` is and how to use it. For that you would land on something like this.
```
javac --source-path ./src -d classes src/Main.java
java --class-path classes Main
```
So you would have been able to introduce `javac`, the concept of ahead of time compilation, `.class` files, and the `--class-path`.
## Step 4.
Once they've made an app [the next thing they'll want](https://www.youtube.com/watch?v=WszAwrlS5GM) is to package it up into a jar.
In the đĸ world, you show them a menu in their editor and what buttons to click.
In the CLI, it's a chance to show them how to use the `jar` tool.
```
jar --create --file app.jar --main-class Main -C classes .
```
## Step 5.
This is where things get tricky, because once they know how to build an app it won't be long before they want to make something that requires a dependency.
And it is this step where things fall apart.
If you are lucky, the dependency they need has no transitive dependencies. You show them how to download a `.jar` file, how to add it to the IDE or where to put it on the `--class-path`, and warn them that they won't be able to get way with that forever.
If you aren't, you need Maven or Gradle. That is by far the easiest way to make sure they get their dependencies.
It is also easy to justify. Chances are any Java job would use one of those.
One problem is that because Maven and Gradle also take over compiling the code, you invalidate their investment in learning how to use `javac` and `jar`. They won't be using either of those from now on.
Another is that both are going to throw a lot in their face. Either an entirely new programming language with Gradle or a relatively beefy `pom.xml` with Maven.
This is what a "blank" Maven gives you in IntelliJ. It's not *horrible*, but it does have some `public static void main(String[] args)`\-like properties.
```
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>untitled92</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
```
You could also use something like [`jbang`](https://www.jbang.dev/), which automatically downloads dependencies declared as comments in the code. But this stops being viable if you want those dependencies for things other than running the code as a script, unfortunately.
So the point of `jresolve` specifically is to let you stick with the command-line flow and avoid pivoting to build tools until later.
You show them how to use it to get dependencies from the internet as well as how to use those dependencies.
```
jresolve \
--output-directory libraries \
pkg:maven/de.gurkenlabs/litiengine@0.8.0
javac \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--source-path ./src \
-d classes \
src/Main.java
java \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--class-path classes \
Main
```
As an aside, while it requires the unpleasant appearance of `ALL-MODULE-PATH` I would argue that showing early that you should put your external dependencies on the `--module-path` is a good thing.
## Step 6.
If you took the path enabled by a tool like `jresolve`, the commands you are asking folks to run likely are getting pretty hard to remember.
It is a good time to introduce some "command runner" mechanism. Some way so they only have to say `compile` instead of a long `javac` incantation.
For this purpose, I have a liking for [just](https://github.com/casey/just), but shell scripts, makefiles, etc. are all valid.
```
help:
just --list
clean:
rm -rf classes
rm -rf libraries
install:
rm -rf libraries
jresolve \
--output-directory libraries \
pkg:maven/de.gurkenlabs/litiengine@0.8.0
compile:
rm -rf classes
javac \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--source-path ./src \
-d classes \
src/Main.java
run:
java \
--module-path libraries \
--add-modules ALL-MODULE-PATH \
--class-path classes \
Main
```
Now that they can do something spiritually like `just compile`, commands no longer need to be produced from memory every time they want to do things with their code.
It also instills the notion that software projects are generally built by a set of named and repeatable processes.
And if you haven't or its just time for a refresher, you can use this as an opportunity to go a little deeper into the command line and explain tools like `cd` and `rm`.
## Step 7.
Now that they know how to use dependencies and can run somewhat involved processes in the CLI, you can show them how to package their code to share with someone who doesn't have Java.
If they've made games and other such gui things, then you can show them `jpackage`. Have them make a `jar` with their classes and show them the flags to include their dependencies and make an installer.
If you've kept more of a server-y focus, maybe you'd just show them how to copy files to a remote machine, maybe you'd go through something like docker and show them the commands to build images.
But at this point they have some idea of how to "ship" their code.
## Step 8.
Now that they have all the mechanisms to deliver code from concept to product, they are going to start making big projects.
At least some students will have an idea for a game or a website or similar they're going to invest a lot of time in, but also the assignments you are giving will probably require more structure. A thing I've seen in a lot of curriculums is to have everyone do the `M` part of an `MVC` type assignment and swap `M`s with another group and write the `V` and `C` using that.
As such, it is as good a time as any to introduce modules.
The path of least resistance would be to introduce the multi-module format that `javac` understands. I.E you have a top level directory for each module that has the module's name.
```
some.mod/
src/
module-info.java
some/
mod/
...
other.mod/
src/
module-info.java
other/
mod/
...
```
```
javac \
-d compiled \
--module-path libraries \
--module-source-path "./*/src" \
--module some.mod,other.mod
```
That will require talking about visibility and packages, so it's a good point to also start talking about higher level concepts like encapsulation and library contracts.
## Step 9.
Maybe this can be done a bit sooner, but you definitely need to show those goobers how to write unit tests now.
The best way to do this is to show them how to use `junit`.
```
java --module-path libraries:compiled \
--add-modules ALL-MODULE-PATH \
org.junit.platform.console.ConsoleLauncher execute --scan-modules
```
Maybe there can be a `junit` executable ready via some mechanism, but either way all the mechanics of even this relatively verbose incantation have been shown.
And this is a great point to introduce the practice of having a separate `test` folder. Also potentially `resources` since tests can use those as a source of test data.
## Step 10.
At some point now that they know how to write code, write tests, design modules, etc. It would be a good point to get into library writing. Not everyone will, but some will try their hand.
It's at this point that learning Maven or Gradle probably becomes needed, though I think with a smidgen more tooling that can be delayed. Maybe just something to generate a POM + `jreleaser` would be enough.
## Step N.
Then, at some point, they have need for a real build tool. I won't opine on this, but I think some people wouldn't ever reach this step.
They will have already gotten a relatively deep understanding of the underlying tools, naturally come across the concept of a build task, know what a library is and what Maven coordinates are and do, and they will have enough context to know why Maven would choose `src/main/java` as the place to put code.
I think this is a healthier level to engage with build-tools at. Understanding what tasks they automate because you've done those tasks manually.
It also gives a firmer foundation for the more exotic parts of tooling like agents, AppCDS, annotation processors, etc. Build tools aren't always the most intuitive with those.
## Conclusion
This might not be appropriate for all curriculums. Sometimes you are in a boot-camp and you just gotta be employable with Spring in 6 months.
But when the goal of an education isn't optimizing time to employment, I think teaching with the command-line first has value. I just think that in order for it to be actually practical, a few more pieces need to be in place.
So that aspiration is what `jresolve` is for. It is what whatever CLI tool I make next will probably be for. That's the vision. Have the JDK be enough, by itself, to get bootstrapped into modern software development. Lower the barrier of entry to be around that of JavaScript and Python.
***
Tell me what I got wrong in the comments below.
***
#### [\<- Index](https://mccue.dev/) |
| Shard | 76 (laksa) |
| Root Hash | 1430577681150262276 |
| Unparsed URL | dev,mccue!/pages/1-11-24-cli-flow s443 |