Definition
Two separate meanings of "two main methods":
- Multiple classes with main: Perfectly legal and common. Each class is an independent entry point. You choose which to run via
java ClassNameor the jar manifest. - Overloaded main in one class: Also legal.
main(String[])andmain(int)can coexist. Only theString[]version is the JVM entry point.
A bank building with multiple front doors – one for retail customers, one for corporate, one for staff. Each door (main method in a different class) leads to a different service. The signage on the building (MANIFEST.MF) indicates which door is the default entrance.
Understanding the Concepts
Multiple classes with main
Yes, multiple classes in the same project can each have their own main(String[] args). This is perfectly legal and very common in real projects. Each class with a main method is an independent entry point. You choose which one to run by specifying the class name.
// File: TransferApp.java
package com.bank;
public class TransferApp {
public static void main(String[] args) {
System.out.println("Running transfer batch...");
}
}
// File: ReportApp.java
package com.bank;
public class ReportApp {
public static void main(String[] args) {
System.out.println("Running daily report...");
}
}
# Choose which to run
java -cp target/classes com.bank.TransferApp
# Output: Running transfer batch...
java -cp target/classes com.bank.ReportApp
# Output: Running daily report...
How does the jar manifest work?
When packaging a jar, the MANIFEST.MF file specifies the default entry point. Running the jar without specifying a class uses this default. You can override it on the command line.
# META-INF/MANIFEST.MF
Main-Class: com.bank.TransferApp
# Default entry point from manifest
java -jar bank-service.jar
# Runs com.bank.TransferApp.main()
# Override with explicit class
java -cp bank-service.jar com.bank.ReportApp
# Runs com.bank.ReportApp.main()
Can you overload main in a single class?
Yes. You can define multiple methods named main with different parameter types. Only the String[] args version is the JVM entry point. The others are regular methods.
package com.bank;
public class BankApp {
public static void main(String[] args) {
System.out.println("JVM entry point");
main(42); // calls the overloaded version
}
public static void main(int code) {
System.out.println("Overloaded main: " + code);
}
}
JVM entry point
Overloaded main: 42
The JVM ignores main(int) when looking for the entry point. It only looks for public static void main(String[]).
When is this useful in banking?
Having multiple main classes in one codebase is the standard approach for banking projects that share domain logic across different runtimes.
| Class | Purpose |
|---|---|
| TransferBatchApp | Nightly batch transfer processing |
| InterestCalculationApp | Monthly interest computation |
| MigrationApp | One-time data migration tool |
| ApiServerApp | Spring Boot REST API server |
All four share the same Account, Transaction, and TransferService classes. Only the entry points differ.
How do you configure it in Maven or Gradle?
<!-- Maven: specify main class in pom.xml --syn-kw">>
syn-kw"><pluginsyn-kw">>
syn-kw"><groupIdsyn-kw">>org.apache.maven.pluginssyn-kw"></groupIdsyn-kw">>
syn-kw"><artifactIdsyn-kw">>maven-jar-pluginsyn-kw"></artifactIdsyn-kw">>
syn-kw"><configurationsyn-kw">>
syn-kw"><archivesyn-kw">>
syn-kw"><manifestsyn-kw">>
syn-kw"><mainClasssyn-kw">>com.bank.TransferBatchAppsyn-kw"></mainClasssyn-kw">>
syn-kw"></manifestsyn-kw">>
syn-kw"></archivesyn-kw">>
syn-kw"></configurationsyn-kw">>
syn-kw"></pluginsyn-kw">>
// Gradle: application plugin
application {
mainClass.set('com.bank.TransferBatchApp')
}
What are common mistakes?
- Forgetting to set Main-Class in the manifest.
java -jar app.jarfails with "no main manifest attribute." - Two main methods in the same class with the same parameters. That is a compile error (duplicate method), not overloading.
- Assuming the JVM picks one automatically. You must specify which class to run.
What should a senior engineer know?
- Spring Boot apps have one @SpringBootApplication main. Additional entry points should be separate classes or use Spring profiles.
- Docker ENTRYPOINT specifies the main class.
ENTRYPOINT ["java", "-jar", "app.jar"]uses the manifest. Override withENTRYPOINT ["java", "-cp", "app.jar", "com.bank.MigrationApp"]. - In a multi-module project, each module can have its own main class. The build tool produces separate jars with their own manifests.
- At National Bank of India, Rajesh organizes the codebase so each deployable service has exactly one main class, but utility tools like the data migrator are separate modules that share the same domain library.
Visual Overview
Project with multiple main classes:
com.bank.TransferBatchApp.main(String[])
com.bank.ReportApp.main(String[])
com.bank.MigrationApp.main(String[])
│
├─ java -jar app.jar → uses MANIFEST.MF Main-Class
├─ java -cp app.jar com.bank.ReportApp → explicit class
└─ Docker ENTRYPOINT → specifies which to run
Key Takeaway
Yes, you can have multiple main methods in a Java application. Each class can have its own public static void main(String[] args), and you choose which one to run by specifying the class name. In a jar file, the MANIFEST.MF Main-Class attribute selects the default entry point.
This is common in banking projects: one main for the batch processor, one for the API server, one for migration tools, all sharing the same domain classes and data access layer.
One sentence to remember: multiple classes can each have main – you choose which one to run via the command line or the jar manifest.
---