7
\$\begingroup\$
cd "$(dirname "$0")"
javac -d . -sourcepath Source Source/project/Main.java
rm "Project.jar" 2>"/dev/null"
jar cfm "Project.jar" "Manifest.txt" project/*

This script would be placed in a Project directory, in which is Manifest.txt and a Source directory which contains the base package, i.e., Main.java would start with package project;. The script would compile the Java into classes, creating a directory of name project inside the Project directory, and then from the class files create Project.jar. I do not have any IDEs installed, but is this typically how they work to compile a project with multiple .java files into a single .jar file?

\$\endgroup\$

2 Answers 2

15
\$\begingroup\$

No #! line to specify interpreter. Perhaps not so important for something that's portable shell, but still helpful to write #!/bin/sh.

No checking that cd was successful. We really don't want to continue if that fails for any reason. Similarly if javac fails, we want to exit with non-zero status. We could add || exit after all commands, but it's easier and simpler to begin the script with set -e.

I'm guessing the redirection of rm's standard error is to cope with Project.jar not existing. I suggest using rm -f instead, which is silent in that case (but will remove read-only files, assuming the directory is writable).

Using shell might work for the short term, but as your project grows, you'll find that going through all the steps unconditionally becomes more and more time-consuming. That's the point to move to a tool that's designed for resolving dependencies and orchestrating builds, such as Ant or Make; other tools are available and recommended by Torben which might also be suitable.

\$\endgroup\$
9
  • 11
    \$\begingroup\$ Make and Ant in 2023? Did I miss an obvious clue about this being a joke thread? :) The de-facto build tools for Java projects are Maven and Gradle and they have been so for many years now. \$\endgroup\$ Feb 15 at 6:07
  • 8
    \$\begingroup\$ @TorbenPutkonen: Makefile has one drawback: it hasn't changed much in 40 years. Makefile has one advantage: it won't change much in the next 40 years. If you try to compile a Maven/Gradle project in 5 years, it will probably first complain about incorrect JAVA_HOME, broken dependencies and missing URLs. For a small project, as described by OP, makefile should be good enough. For anything bigger, by all means, use Maven/Gradle. \$\endgroup\$ Feb 15 at 8:31
  • 2
    \$\begingroup\$ @EricDuminil If your project is not maintained for 5 years, you very likely have bigger issues than the build process failing. :) And based on my experience with make and Maven, there is not a project so small that would justify the manual labour required to write a Makefile over setting up maven. That's like suggesting that it's better that you walk instead of buying a bicycle because it will have flat tires after you have stored it for five years. \$\endgroup\$ Feb 15 at 8:36
  • 3
    \$\begingroup\$ My comment was sadly out-of-date, as I haven't caught up with the cool kids yet. The codebase I work with day-in and day-out is large and old, so I've not moved on from Ant. I'd still regard it as more suitable than "make"... \$\endgroup\$ Feb 15 at 8:42
  • 3
    \$\begingroup\$ As a shell review, perhaps I should have just said "a tool designed for the job," rather than starting all this discussion. Personally, I'd just start with Make rather than learning a new tool, but if you're already as fluent with something more Java-specific, then that's probably more appropriate. In any case, it likely depends on how much of your project is written in Java (and how much time you want to spend editing your rules for "updated" tools). \$\endgroup\$ Feb 15 at 9:15
18
\$\begingroup\$

Using custom shell scripts is not a typical way to compile and package multiple source files into a Jar-package. The de-facto standard tools for building Java projects and managing their dependencies are Maven and Gradle. Maven being mostly Java-centric and Gradle being truly "multi-language." The learning curve may seem steep compared to just writing a shell script but the payoff comes as soon as you need to add a 3rd party Jar file (junit and logging are almost always the first ones) to your project.

Regarding the shell script in itself, Toby's answer is spot on.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.