如何在仅含Java的环境中从同一Uber Jar运行多Scala任务?
Let's break down how to fix this issue and run both of your Scala tasks from the same Uber Jar without a unified entry point.
1. Fix the Runtime Command: Use Fully Qualified Class Names
The immediate error you're seeing (Could not find or load main class MyClass) is because you're using the short class name instead of the fully qualified class name (which includes the package your classes live in). Since both objects are in the mypackage package, you need to reference them with their full paths when running:
# Run the first task java -cp myapp.jar mypackage.MyClass # Run the second task java -cp myapp.jar mypackage.MyClass2
Before moving further, double-check that your Uber Jar contains these classes by running jar tf myapp.jar — you should see entries for mypackage/MyClass.class and mypackage/MyClass2.class in the output.
2. Configure SBT Assembly to Preserve Multiple Main Classes
If you're using the sbt-assembly plugin to build your Uber Jar, you need to ensure it doesn't exclude or prioritize one main class over the other. By default, sbt-assembly will warn you if multiple main classes are detected, but you can explicitly configure it to allow this and avoid setting a single default entry point.
Add these settings to your build.sbt:
// Disable setting a default main class (forces you to specify it at runtime) mainClass in assembly := None // Standard merge strategy for Uber Jars (adjust if you have conflicting resource files) assemblyMergeStrategy in assembly := { case PathList("META-INF", xs @ _*) => MergeStrategy.discard case x => MergeStrategy.first }
This setup guarantees both of your main classes are included in the final Uber Jar, with no hardcoded default entry point — you retain full control over which task to run via the command line.
3. Verify the Build
Run sbt assembly to rebuild your Uber Jar. Once the build finishes, test both commands again using the fully qualified class names. They should execute without the "could not find main class" error now.
A quick side note: Scala compiles object main classes into two files (e.g., MyClass.class and MyClass$.class). The MyClass.class file is the one that contains the standard Java main method, so referencing mypackage.MyClass is exactly what the JVM needs to locate the entry point.
内容的提问来源于stack exchange,提问作者schwadan

