Core Java Concepts and Implementation Details

Classpath Configuration

Classpath defines locations where the JVM searches for compiled classes, libraries, and resources during execution. It can be specified via:

  • Command line: java -cp app.jar;libs/* com.sample.MainApp
  • Environment variable: set CLASSPATH=app.jar;libs/*
  • Executable JAR manifest:
Class-Path: libs/dep1.jar libs/dep2.jar

Tomcat Deployment and Class Loading

Spring Web WAR Startup

For a traditional Spring Web WAR deployed in Tomcat, startup is triggered via web.xml:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Catalina Component

Catalina is Tomcat's core engine managing servlet container responsibilities.

Custom Class Loading Order

Tomcat uses a modified delegation model to isolate web apps:

  1. Bootstrap loader (JVM internals)
  2. System loader (Tomcat bootstrap classes)
  3. WebAppClassLoader loads WEB-INF/classes
  4. WebAppClassLoader loads WEB-INF/lib
  5. Common loader reads CATALINA_HOME/lib

Because WEB-INF/classes precedes WEB-INF/lib in loading priority, placing a class with identical package and name under classes overrides the library version—useful for hotfixes but risky.

MANIFEST.MF Usage

Placed inside JARs, it declares metadata:

  • Main-Class sets entry point
  • Class-Path lists dependencies
  • Additional fields like Implementation-Version appear in Spring Boot jars

Example access via JarFile enables runtime retrieval of SDK version for diagnostics.

Efficient File Copy with FileChannel

try (FileChannel srcCh = new FileInputStream("src.dat").getChannel();
     FileChannel destCh = new FileOutputStream("dest.dat").getChannel()) {
    long remaining = srcCh.size();
    long position = 0;
    while (remaining > 0) {
        long transferred = srcCh.transferTo(position, remaining, destCh);
        position += transferred;
        remaining -= transferred;
    }
}

Looping ensures completion since transferTo may transfer less than requested.

Resource Loading Differences

  • Class.getResource() delegates to class loader; path starting / is absolute, otherwise relative to the class's package.
  • ClassLoader.getResource() accepts only absolute paths (no leading /).

Example with resources/conf.txt:

// null, relative without leading slash
URL res1 = MyClass.class.getResource("conf.txt");
// valid, absolute path
URL res2 = MyClass.class.getResource("/conf.txt");
// valid
URL res3 = MyClass.class.getClassLoader().getResource("conf.txt");
// null, loader ignores leading slash
URL res4 = MyClass.class.getClassLoader().getResource("/conf.txt");

Used in frameworks like Spring to scan META-INF/spring.factories.

SQL_CALC_FOUND_ROWS Pitfall

Legacy pagination pattern:

SELECT SQL_CALC_FOUND_ROWS id, flow_id FROM flow_mapping;
SELECT FOUND_ROWS();

Can degrade performance without proper indexing and is deprecated in MySQL 8.0.

Retrieve SDK Version at Runtime

Embed version in resources/META-INF/module.info:

module.type=demo-sdk
module.name=demo-module
module.version=${project.version}

Load via:

Properties props = new Properties();
try (InputStream in = MyClass.class.getClassLoader().getResourceAsStream("META-INF/module.info")) {
    props.load(in);
    String ver = props.getProperty("module.version");
}

Extract Root Cause from Wrapped Exceptions

ThrowableAnalyzer analyzer = new ThrowableAnalyzer();
Throwable[] chain = analyzer.determineCauseChain(ex);
RuntimeException rootEx = analyzer.getFirstThrowableOfType(RuntimeException.class, chain);

Naming Classes Beyond Helper

Names like Helper often mask multiple responsibilities. Prefer specific roles:

CSVParser.parse(str);
CSVBuilder.create(data);

Interface-Based Version Compatibility

Define incompatible parts via interfaces and inject implementations using SPI to switch versions dynamically.

Bitwise Operations

int flag1 = 1 << 2;   // 4
int flag2 = 1 << 8;   // 256
int combined = flag2 | flag1;
System.out.println((combined & flag1) == flag1); // true
System.out.println((~flag1 & combined));          // flag2

Custom List Ordering

List<String> template = Arrays.asList("a", "c", "d");
List<String> input = Arrays.asList("a", "d", "c", "d", "c", "e");
List<Pair<String, Integer>> indexed = input.stream()
    .map(val -> new Pair<>(val, template.indexOf(val) == -1 ? Integer.MAX_VALUE : template.indexOf(val)))
    .sorted(Comparator.comparing(Pair::getValue))
    .collect(Collectors.toList());

JIT Compilation: C1 vs C2

  • C1 compiles quickly for fast startup; less optimized.
  • C2 performs extensive optimizations using runtime profiling; suited for long-running services.
  • JVM may use both adaptively; specifying -server does not disable C1 entirely.

Java Process Termination

  • Runtime.exit() sends SIGTERM; halt() forces termination (SIGKILL).
  • Process exits when all non-daemon threads complete or exit() is called.
  • Daemon threads do not block JVM shutdown.

Thread OOM Impact

A single thread encountering OutOfMemoryError does not terminate the process; other threads may continue unless memory exhaustion cascades. Each thread handles its own uncaught exceptions via dispatchUncaughtException.

Thread Pool Nuances

Core Size Zero

With corePoolSize=0, first task creates a thread; subsequent tasks queue until capacity is hit, then new threads spawn—behaving like a single worker.

Deadlock Risk

Parent and child tasks sharing a single-thread pool can deadlock if they wait on each other.

Exception Handling

  • execute() propagates exceptions to console.
  • submit() wraps exceptions in Future; call get() to observe them.
  • Uncaught exception handlers do not intercept submit() errors.

Best practice: wrap task logic in try-catch and log; configure pool with global exception logging.

Dynamic Log Level Adjustment

Tools like Alibaba Arthas enable live modification of logger levels. Alternatively, integrate Logback's API with configuration management for remote updates. Spring Boot Admin offers similar capabilities.

Embedded Web Server Launch

Middleware often embeds Jetty for status endpoints. Refer to Kafka Connect's RestServer implementation.

Read Last Line of File Efficiently

Using Apache Commons IO:

ReversedLinesFileReader reader = new ReversedLinesFileReader(file);
System.out.println(reader.readLine());
reader.close();

Access Test Resources

String filePath = MyClass.class.getClassLoader().getResource("data.txt").getFile();
File fileObj = new File(filePath);

Note: Path reflects the compiled target/classes location.

Delayed Appender Shutdown in Logback

<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook" />

Ensures pending logs flush during JVM exit.

DNS Cache Behavior

Java caches DNS results; changes in DNS records may not reflect until cache expiry or JVM restart. Consult cloud provider docs for TTL tuning.

Field Hiding and Getters

Subclass fields hide superclass fields of same name. Method calls resolve based on actual object's method definition, not field visibility. Overriding getter in subclass can control which field value is returned.

Externalized Constants via JAXB

Define mappings in XML and parse with JAXBContext in Java 8 to avoid hardcoding labels in code or database.

Drawbacks of JDK Serialization

  • Tied to Java object structure; fragile across versions.
  • Security risks with untrusted streams.
  • Slower compared to formats like JSON or Protobuf.

Thick vs Thin Client

Refers to distribution of business logic. Thick clients handle more functionality locally; trend moves toward richer client capabilities.

String.getBytes() Charset Sensitivity

Always specify charset to avoid platform-dependent results:

byte[] utf8 = str.getBytes(StandardCharsets.UTF_8);
byte[] defEnc = str.getBytes(); // may differ

Arrays as Objects

Arrays are full-fledged objects, enstantiated by JVM, with Object as superclass. They exhibit object behavior and can invoke Object methods.

Volatile Usage

Ensures visibility of primitive fields across threads. For references, only the pointer visibility is guaranteed; object internals may still suffer consistency issues.

Atomicity vs Thread Safety

  • Thread safety: Correct concurrent access to shared data.
  • Atomicity: Indivisible operation sequence.

Atomicity implies thread safety for that operation. Achieve via:

  • Single-threaded execution
  • java.util.concurrent.atomic classes
  • synchronized blocks/methods

Watch Filesystem Changes

Use java.nio.file.WatchService to monitor create, modify, delete events.

Display Default JVM Options

Run with:

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log

Side Effects in Methods

A side effect alters external state (instance fields, statics, mutable arguments, I/O). Pure functions avoid side effects, easing reasoning and testing.

JVM Diagnostic Tools

Arthas subsumes features of BTrace, Greys, and others; preferred for comprehensive troubleshooting.

Lock Identification Pattern

Define marker classes solely to label locks in thread dumps:

public class LogbackLock {} 

Naming Conventions Insight

Good names reflect modeled concepts:

  • *Factory – creator instances
  • *Context – scoped state carrier
  • *Appender – destination writer
  • *Aware – capability subscriber
  • *Tracker – dynamic manager
  • *Binder – association mechanism These patterns improve clarity and maintainability.

Tags: java JVM Tomcat Concurrency Performance

Posted on Fri, 22 May 2026 20:41:36 +0000 by (RL)Ian