# Application.bx

## 🌏 Overview

`Application.bx` is BoxLang's **application framework** - a powerful feature that allows you to define virtual applications in memory with isolated settings, lifecycle events, and persistence scopes. This works across **all BoxLang runtimes**: web servers (CommandBox, MiniServer), CLI applications, Lambda functions, desktop applications, and more.

### The Big Picture: Virtual Applications

BoxLang creates isolated virtual applications within a single JVM process:

```
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                    BoxLang Runtime (JVM)                 ┃
┃                                                          ┃
┃  ┌──────────────────────-┐   ┌──────────────────────┐    ┃
┃  │  Application: "App1"  │   │  Application: "App2" │    ┃
┃  │  ───────────────────  │   │  ─────────────────── │    ┃
┃  │  📦 application{}     │   │  📦 application{}    │    ┃
┃  │  👤 session{}         │   │  👤 session{}        │    ┃
┃  │  ⚙️  Config Settings  │   │  ⚙️  Config Settings │    ┃
┃  │  🗄️  Datasources      │   │  🗄️  Datasources     │    ┃
┃  │  🧩 Lifecycle Events  │   │  🧩 Lifecycle Events │    ┃
┃  └───────────────────────┘   └──────────────────────┘    ┃
┃          ↑ ↑ ↑                     ↑ ↑ ↑                 ┃
┃       Requests from              Requests from           ┃
┃       /app1/** tree              /app2/** tree           ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
```

Each `Application.bx` creates a completely isolated virtual application with its own memory space, configuration, and lifecycle - all running in the same JVM.

{% hint style="success" %}
**Key Feature**: With a single `Application.bx` file or a hierarchy of them, you can create virtual applications in memory, each with its own isolated `application`, `session`, and configuration space - all within the same JVM process.
{% endhint %}

### What is Application.bx?

`Application.bx` is a special BoxLang class file that serves two primary purposes:

1. **Application Configuration** - Define application-wide settings in the pseudo-constructor using the `this` scope:
   * Application name and timeouts
   * Datasource configurations
   * Caching strategies
   * Session management
   * File mappings and class paths
   * Java library integration
   * Security settings
   * Custom schedulers and much more
2. **Lifecycle Event Handlers** - Implement callback methods that BoxLang executes automatically at key points:
   * Application startup/shutdown
   * Session creation/destruction
   * Request processing (start, execute, end)
   * Error handling
   * Missing templates
   * Class invocations

### How It Works

When BoxLang executes any code (web request, CLI script, Lambda function), it searches for `Application.bx` starting from the current directory and traversing **upward** through parent directories until found or reaching the root.

#### Application.bx Discovery Process

```
Request: /projects/myapp/api/users/handler.bx

Step 1: Check /projects/myapp/api/users/Application.bx    ❌ Not found
Step 2: Check /projects/myapp/api/Application.bx          ❌ Not found
Step 3: Check /projects/myapp/Application.bx              ✅ Found!
        └─> Use this Application.bx for the request
```

#### Nested Applications Example

## 📋 Table of Contents

* [Overview](#overview)
* [Complete Example](#complete-example)
* [Configuration Settings](#configuration-settings)
* [Lifecycle Events](#lifecycle-events)
* [Virtual Applications - A Critical Feature](#virtual-applications---a-critical-feature)
* [Additional Resources](#additional-resources)

```
📁 /projects/myapp/
   📄 Application.bx          ← Found! Used for entire app
   📁 /admin/
      📄 Application.bx       ← Nested app with different settings
      📄 dashboard.bxm
   📁 /api/
      📄 handler.bx
   📄 index.bxm
```

{% hint style="info" %}
**Directory Scope**: The `Application.bx` file applies to its directory and all subdirectories. Any BoxLang code in that tree will automatically use this application context.
{% endhint %}

### Transient Nature

`Application.bx` is **instantiated on every request** - this is a critical feature that provides multi-tenancy for any BoxLang web application out of the box:

✅ **Dynamic Configuration** - Modify settings per-request based on conditions:

* Switch datasources based on subdomain or user
* Adjust session timeouts for bot detection
* Enable/disable features based on environment
* Dynamic security rules

✅ **Request-Level Customization** - Each request can have unique behavior while sharing the same application memory space

⚠️ **Performance Consideration** - Since it runs on every request, keep the pseudo-constructor logic optimized. Use the `application` scope for expensive operations that should only run once.

#### Application.bx Instantiation vs Application Memory

```
Request #1                Request #2                Request #3
    │                         │                         │
    ▼                         ▼                         ▼
┌─────────┐              ┌─────────┐              ┌─────────┐
│ App.bx  │ New Instance │ App.bx  │ New Instance │ App.bx  │
│Instance │◄─────────────│Instance │◄─────────────│Instance │
└────┬────┘              └────┬────┘              └────┬────┘
     │                        │                        │
     │  Sets this.name        │  Sets this.name        │  Sets this.name
     │  Reads this.settings   │  Reads this.settings   │  Reads this.settings
     │                        │                        │
     └────────┬───────────────┴────────────┬───────────┘
              │                            │
              ▼                            ▼
     ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
     ┃        Persistent Application Memory      ┃
     ┃  ──────────────────────────────────────── ┃
     ┃  application.startedAt = "2024-01-01"     ┃
     ┃  application.cachedData = [...]           ┃
     ┃  application.version = "1.0.0"            ┃
     ┃                                           ┃
     ┃  ← Shared across ALL requests             ┃
     ┃  ← Survives until applicationTimeout      ┃
     ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
```

**The Key Insight**:

* 🔄 **Application.bx class** = Created and destroyed with **every request**
* 💾 **`application` scope** = Persists in memory and shared across all requests

```js
class {
    this.name = "MyApp";

    // ✅ Good: Simple configuration
    this.datasource = "mainDB";

    // ❌ Avoid: Expensive operations in pseudo-constructor
    // this.data = queryExecute("SELECT * FROM huge_table");

    function onApplicationStart() {
        // ✅ Good: Expensive operations run once
        application.cachedData = queryExecute("SELECT * FROM huge_table");
    }
}
```

### Multi-Runtime Support

`Application.bx` works seamlessly across all BoxLang deployment targets:

| Runtime                    | Use Case                    | Application.bx Behavior                         |
| -------------------------- | --------------------------- | ----------------------------------------------- |
| **Web Servers**            | CommandBox, MiniServer, JEE | Full support with sessions, cookies, web scopes |
| **CLI**                    | Scripts, automation, tools  | Application scope, no web-specific features     |
| **AWS Lambda**             | Serverless functions        | Application scope, cold start optimization      |
| **Google Cloud Functions** | Serverless functions        | Application scope, cold start optimization      |
| **Desktop**                | Electron, JavaFX apps       | Application scope, local persistence            |

{% hint style="warning" %}
**Web-Only Scopes**: Features like `session`, `cookie`, `form`, `url`, and `cgi` scopes only exist in web runtimes. Structure your code to handle different runtime contexts gracefully.
{% endhint %}

## 📝 Complete Example

{% code title="Application.bx" %}

```js
class {

    // ========================================
    // APPLICATION IDENTITY
    // ========================================

    this.name = "MyAwesomeApp";
    // Never expires (preferred) - only set if you need auto-restart
    this.applicationTimeout = createTimeSpan( 0, 0, 0, 0 );

    // ========================================
    // SESSION MANAGEMENT (Web Runtime Only)
    // ========================================

    this.sessionManagement = true;
    this.sessionTimeout = createTimeSpan( 0, 0, 60, 0 ); // 1 hour
    this.sessionStorage = "default"; // Cache name or "memory"
    this.setClientCookies = true;
    this.setDomainCookies = false;

    // Session cookie configuration (web runtime only)
    this.sessionCookie = {
        httpOnly : true,      // Prevent JavaScript access
        secure : false,       // HTTPS only when true
        sameSite : false,     // Third-party cookie access
        sameSiteMode : "Lax", // "Strict", "Lax", or "None"
        timeout : createTimeSpan( 365, 0, 0, 0 )
    };

    // ========================================
    // DATASOURCES
    // ========================================

    this.datasource = "mainDB"; // Default datasource for any query or ORM

    this.datasources = {
        "mainDB" : {
            driver : "mysql",
            host : "localhost",
            port : 3306,
            database : "myapp",
            username : getSystemSetting( "DB_USER" ),
            password : getSystemSetting( "DB_PASS" )
        }
    };

    // ========================================
    // CACHING
    // ========================================

    this.caches = {
        "template" : {
            provider : "BoxCache",
            properties : {
                maxObjects : 200,
                defaultTimeout : 3600,
                evictionPolicy : "LRU"
            }
        }
    };

    // ========================================
    // MAPPINGS
    // ========================================

    this.mappings = {
        "/app" : expandPath( "./app" ),
        "/models" : expandPath( "./models" )
    };

    // ========================================
    // JAVA INTEGRATION
    // ========================================

    this.javaSettings = {
        loadPaths : [ expandPath( "./lib" ) ],
        loadSystemClassPath : false,
        reloadOnChange : false
    };

    // ========================================
    // CUSTOM SCHEDULERS
    // ========================================

    this.schedulers = [ "tasks.MaintenanceScheduler" ];

    // ========================================
    // CUSTOM WATCHERS
    // ========================================

    watcherListener = new app.listeners.HotReloadListener()

    this.watchers = {
        sourceWatcher : {
            paths : [ expandPath( "./src" ) ],
            listener : watcherListener,
            recursive : true,
            debounce : 250,
            atomicWrites : true,
            errorThreshold : 10
        }
    }

    // ========================================
    // LIFECYCLE EVENTS
    // ========================================

    function onApplicationStart() {
        application.startedAt = now();
        application.version = "1.0.0";
        return true;
    }

    function onApplicationEnd( struct applicationScope ) {
        // Cleanup logic
    }

    function onSessionStart() {
        session.startedAt = now();
    }

    function onSessionEnd( struct sessionScope, struct applicationScope ) {
        // Log session end, cleanup resources
    }

    function onRequestStart( string targetPage ) {
        // Security checks, request initialization
        return true; // Return false to abort request
    }

    function onRequest( string targetPage ) {
        // Wrap request with custom logic
        include arguments.targetPage;
    }

    function onRequestEnd() {
        // Cleanup, logging, metrics
    }

    function onError( any exception, string eventName ) {
        // Custom error handling
        writeLog( "Error in #eventName#: #exception.message#" );
        return true; // Return true if handled
    }

    function onAbort( required string targetPage ) {
        // Handle abort() calls
    }

    function onMissingTemplate( required string targetPage ) {
        // Custom 404 handling
        return false; // Return true if handled
    }

    function onClassRequest( className, method, struct args ) {
        // Intercept remote class invocations
    }
}
```

{% endcode %}

## ⚙️ Configuration Settings

All configuration settings are defined in the pseudo-constructor using the `this` scope. Here's a comprehensive reference of available settings:

### Core Application Settings

| Setting                   | Type     | Default      | Description                                                               |
| ------------------------- | -------- | ------------ | ------------------------------------------------------------------------- |
| `this.name`               | string   | *Generated*  | Unique application name. Defines the memory space reservation             |
| `this.applicationTimeout` | timespan | 0,0,0,0      | Application lifetime. Default `0,0,0,0` = **never expires** (recommended) |
| `this.locale`             | string   | JVM locale   | Default locale (e.g., "en\_US", "es-ES")                                  |
| `this.timezone`           | string   | JVM timezone | IANA timezone (e.g., "UTC", "America/New\_York")                          |

### Session Management (Web Runtime)

| Setting                  | Type     | Default    | Description                                |
| ------------------------ | -------- | ---------- | ------------------------------------------ |
| `this.sessionManagement` | boolean  | `false`    | Enable session tracking                    |
| `this.sessionTimeout`    | timespan | 0,0,30,0   | Session lifetime (30 minutes default)      |
| `this.sessionStorage`    | string   | `"memory"` | Cache name for session storage or "memory" |
| `this.setClientCookies`  | boolean  | `true`     | Automatically set session cookies          |
| `this.setDomainCookies`  | boolean  | `false`    | Share cookies across subdomains            |

### Session Cookie Configuration (Web Runtime)

```js
this.sessionCookie = {
    httpOnly : true,              // Prevent JavaScript access
    secure : false,               // HTTPS only
    sameSite : false,             // Third-party cookie access
    sameSiteMode : "Lax",         // "Strict", "Lax", "None"
    timeout : createTimeSpan( 365, 0, 0, 0 )
};
```

### Datasources

| Setting                  | Type   | Description                 |
| ------------------------ | ------ | --------------------------- |
| `this.datasource`        | string | Default datasource name     |
| `this.defaultDatasource` | string | Alias for `this.datasource` |
| `this.datasources`       | struct | Datasource definitions      |

**Example:**

```js
this.datasources = {
    "myDB" : {
        driver : "mysql",
        host : "localhost",
        database : "appdb",
        username : getSystemSetting( "DB_USER" ),
        password : getSystemSetting( "DB_PASS" )
    }
};
```

See [datasource configuration](https://github.com/ortus-boxlang/boxlang-docs/blob/v1.x/boxlang-language/syntax/datasources/README.md#datasource-configuration) for full configuration details.

### Caching

Define application-specific caches that BoxLang manages automatically:

```js
this.caches = {
    "template" : {
        provider : "BoxCache",
        properties : {
            maxObjects : 200,
            defaultTimeout : 3600,
            evictionPolicy : "LRU",
            objectStore : "ConcurrentStore"
        }
    }
};
```

See [Caching documentation](/boxlang-framework/caching.md) for full configuration details.

### Mappings

Define virtual paths for class and file resolution:

```js
this.mappings = {
    "/app" : expandPath( "./app" ),
    "/models" : expandPath( "./models" ),
    "/shared" : "/var/shared/libraries"
};
```

As of BoxLang 1.6.0, mappings support both simple (string) and complex (struct) formats:

```js
this.mappings = {
    // Simple format (external by default)
    "/public" : expandPath( "./public" ),

    // Complex format with external flag
    "/internal" : {
        path : expandPath( "./internal" ),
        external : false  // Not accessible via web
    }
};
```

### Java Integration

Load Java libraries and manage class loading:

```js
this.javaSettings = {
    loadPaths : [
        expandPath( "./lib" ),
        expandPath( "./jars/mylib.jar" )
    ],
    loadSystemClassPath : false,  // Include system classpath
    reloadOnChange : false        // Hot-reload on JAR changes
};
```

See [Java Integration documentation](/boxlang-framework/java-integration.md) for details.

### Custom Schedulers

Register scheduler classes that run automatically:

```js
this.schedulers = [
    "schedulers.DailyMaintenance",
    "schedulers.HourlyReports"
];
```

See [Asynchronous Programming documentation](/boxlang-framework/asynchronous-programming.md) for scheduler details.

### Custom Watchers

Register application-scoped file watchers that auto-start when the application starts:

```js
watcherListener = new app.listeners.HotReloadListener()

this.watchers = {
    sourceWatcher : {
        paths : [ expandPath( "./src" ) ],
        listener : watcherListener,
        recursive : true,
        debounce : 250,
        throttle : 0,
        atomicWrites : true,
        errorThreshold : 10
    },
    assetsWatcher : {
        paths : [ expandPath( "./resources" ) ],
        listener : {
            onModify : ( event ) => rebuildAsset( event.path ),
            onEvent : ( event ) => writeLog( text: "Watcher event [#event.kind#] #event.relativePath#", level: "debug" )
        },
        recursive : false
    }
}
```

Watcher listener values support these forms:

| Listener Form      | Example                                            | Notes                                         |
| ------------------ | -------------------------------------------------- | --------------------------------------------- |
| Closure            | `listener : ( event ) => println( event.kind )`    | Handles all events through a single function. |
| Struct of closures | `listener : { onModify : ( e ) => ... }`           | Event-specific handlers such as `onModify()`. |
| Class name string  | `listener : "app.listeners.HotReloadListener"`     | Runtime instantiates the class automatically. |
| Class instance     | `listener : new app.listeners.HotReloadListener()` | Reuses the already created class instance.    |

Watcher definition keys in `this.watchers.<watcherName>` support these values:

| Key              | Type            | Required | Default | Description                                                                     |
| ---------------- | --------------- | -------- | ------- | ------------------------------------------------------------------------------- |
| `paths`          | string or array | Yes      | -       | Directory path or array of directory paths to watch.                            |
| `listener`       | any             | Yes      | -       | Closure, struct of closures, class name string, or class instance.              |
| `recursive`      | boolean         | No       | `true`  | Watch subdirectories recursively.                                               |
| `debounce`       | long            | No       | `0`     | Debounce window in milliseconds.                                                |
| `throttle`       | long            | No       | `0`     | Throttle window in milliseconds.                                                |
| `atomicWrites`   | boolean         | No       | `true`  | Reduce noisy temp-file/rename save events.                                      |
| `errorThreshold` | integer         | No       | `10`    | Consecutive listener errors before watcher auto-stops (`0` disables auto-stop). |

{% hint style="info" %}
Application watchers are namespaced per app as `applicationName:watcherName` and are started automatically during application startup.
{% endhint %}

See [Directory + File Watchers](/boxlang-framework/asynchronous-programming/directory-file-watchers.md) for listener method contracts and complete runtime APIs.

### Security Settings

| Setting                                  | Type    | Default   | Description                                    |
| ---------------------------------------- | ------- | --------- | ---------------------------------------------- |
| `this.invokeImplicitAccessor`            | boolean | *Context* | Enable implicit getters/setters                |
| `this.allowedFileOperationExtensions`    | array   | *Runtime* | File extensions allowed for file operations    |
| `this.disallowedFileOperationExtensions` | array   | *Runtime* | File extensions disallowed for file operations |

See [security configuration](https://github.com/ortus-boxlang/boxlang-docs/blob/v1.x/getting-started/configuration/security/README.md) for full details.

### Advanced Settings

| Setting                     | Type  | Description                        |
| --------------------------- | ----- | ---------------------------------- |
| `this.classPaths`           | array | Global class paths for `.bx` files |
| `this.componentPaths`       | array | Alias for `classPaths`             |
| `this.customComponentPaths` | array | Custom component directories       |

{% hint style="danger" %}
Please note that **ANY** module can also listen to the Application.bx and be able to provide their own settings and configurations. Examples of these are the `bx-mail, bx-orm` and other modules. So make sure you validate those setttings with the appropriate module.
{% endhint %}

## 🔄 Lifecycle Events

`Application.bx` acts as a comprehensive event listener, with BoxLang automatically invoking callback methods at key moments in your application's lifecycle.

### Application Lifecycle

#### `onApplicationStart()`

**Executed once** when the application first starts - when the first request arrives and the application doesn't exist in memory.

```js
function onApplicationStart() {
    application.startTime = now();
    application.config = loadConfiguration();
    application.cache = createCache();

    // Return true to continue, false to abort
    return true;
}
```

**When it runs:**

* First request after server startup
* After application timeout expires
* After `applicationStop()` is called

#### `onApplicationEnd( struct applicationScope )`

**Executed once** when the application shuts down due to timeout or explicit stop.

```js
function onApplicationEnd( struct applicationScope ) {
    // Cleanup: close connections, save state, log metrics
    writeLog( "Application ended after #dateDiff( 's', applicationScope.startTime, now() )# seconds" );
}
```

### Session Lifecycle (Web Runtime Only)

#### `onSessionStart()`

**Executed** when a new user session begins.

```js
function onSessionStart() {
    session.userID = createUUID();
    session.startTime = now();
    session.requestCount = 0;
}
```

#### `onSessionEnd( struct sessionScope, struct applicationScope )`

**Executed** when a session expires or is explicitly terminated.

```js
function onSessionEnd( struct sessionScope, struct applicationScope ) {
    // Log user activity, cleanup session resources
    writeLog( "Session #sessionScope.userID# ended after #sessionScope.requestCount# requests" );
}
```

{% hint style="warning" %}
Session events only fire in **web runtimes** with `sessionManagement = true`.
{% endhint %}

### Request Lifecycle

#### `onRequestStart( string targetPage )`

**Executed** at the start of every request, **before** the target page is processed.

```js
function onRequestStart( string targetPage ) {
    // Security checks
    if ( !isUserLoggedIn() && !isPublicPage( arguments.targetPage ) ) {
        relocate( "/login" );
        return false; // Abort request
    }

    // Request initialization
    request.startTime = getTickCount();
    session.requestCount++;

    return true; // Continue processing
}
```

**Return Value:**

* `true` - Continue processing the request
* `false` - Abort the request (no further processing)

#### `onRequest( string targetPage )`

**Wraps** the entire request execution. You control if/how the target page is included.

```js
function onRequest( string targetPage ) {
    try {
        // Before advice
        setupRequestContext();

        // Execute the target page
        include arguments.targetPage;

        // After advice (only if no errors)
        logSuccessfulRequest();
    }
    catch ( any e ) {
        // Handle request-level errors
        renderErrorPage( e );
    }
}
```

{% hint style="info" %}
**Pattern**: Think of `onRequestStart()` as "before advice" and `onRequest()` as "around advice" in AOP terms. If you implement `onRequest()`, you **must** include the target page yourself.
{% endhint %}

#### `onRequestEnd()`

**Executed** after the request completes, even if errors occurred.

```js
function onRequestEnd() {
    // Logging, metrics, cleanup
    var duration = getTickCount() - request.startTime;
    writeLog( "Request completed in #duration#ms" );
}
```

### Error Handling

#### `onError( any exception, string eventName )`

**Global error handler** - catches any unhandled exceptions in your application.

```js
function onError( any exception, string eventName ) {
    // Log the error
    writeLog(
        type = "error",
        file = "application",
        text = "Error in #eventName#: #exception.message#"
    );

    // Custom error page
    include "errors/500.bxm";

    // Return true if handled, false to let BoxLang handle it
    return true;
}
```

**Parameters:**

* `exception` - The exception struct with `message`, `detail`, `type`, `stacktrace`, etc.
* `eventName` - Which lifecycle event threw the error (e.g., "onRequestStart", "onApplicationStart")

#### `onAbort( required string targetPage )`

**Executed** when `abort()` is called anywhere in the request.

```js
function onAbort( required string targetPage ) {
    writeLog( "Request aborted from: #arguments.targetPage#" );
}
```

### Special Handlers

#### `onMissingTemplate( required string targetPage )`

**Executed** when a requested template doesn't exist - your custom 404 handler.

```js
function onMissingTemplate( required string targetPage ) {
    // Custom 404 logic
    response.setStatus( 404 );
    include "errors/404.bxm";

    // Return true if handled, false for BoxLang's default 404
    return true;
}
```

#### `onClassRequest( className, method, struct args )`

**Intercepts** remote class invocations (HTTP/AMF calls to BoxLang classes).

```js
function onClassRequest( className, method, struct args ) {
    // Security, logging, custom routing
    if ( !hasRemoteAccess( arguments.className, arguments.method ) ) {
        throw( "Access denied" );
    }

    // Delegate to the actual class
    var instance = createObject( arguments.className );
    return invoke( instance, arguments.method, arguments.args );
}
```

### Execution Order

```
📍 Application Starts (first request)
   ↓
1. onApplicationStart()
   ↓
📍 New Session (web runtime)
   ↓
2. onSessionStart()
   ↓
📍 Request Arrives
   ↓
3. onRequestStart( targetPage )
   ↓
4. onRequest( targetPage )  ← Your template executes here
   ↓
5. onRequestEnd()
   ↓
📍 Session Expires
   ↓
6. onSessionEnd( sessionScope, applicationScope )
   ↓
📍 Application Expires
   ↓
7. onApplicationEnd( applicationScope )
```

{% hint style="success" %}
**Framework Integration**: The [ColdBox HMVC Framework](https://www.coldbox.org) leverages these lifecycle methods to provide a rich event-driven architecture. Create a ColdBox app: `coldbox create app MyApp`
{% endhint %}

## 🏗️ Virtual Applications - A Critical Feature

One of BoxLang's most powerful capabilities is the ability to create **multiple virtual applications** within a single JVM process. Each application is a **memory space reservation** with isolated scopes and settings.

### How Virtual Applications Work

Each `Application.bx` with a unique `this.name` creates a separate virtual application. These applications:

✅ Have their own isolated `application` scope and timeout

✅ Have their own isolated `session` scopes (web runtime), caches and timeouts

✅ Can have completely different settings and configurations

✅ Share the same JVM but are logically independent

✅ Can be nested or side-by-side in the directory structure

### Example: Multiple Apps in One Server

```
📁 /var/www/
   📄 Application.bx                    ← Public website app
      this.name = "PublicSite"
   📄 index.bxm

   📁 /admin/
      📄 Application.bx                 ← Admin console app
         this.name = "AdminConsole"
      📄 dashboard.bxm

   📁 /api/
      📄 Application.bx                 ← REST API app
         this.name = "RestAPI"
      📄 handler.bx
```

**Result**: Three independent applications running in the same JVM:

* `PublicSite` - Public website with 30-day application timeout
* `AdminConsole` - Admin area with 1-hour session timeout and different datasource
* `RestAPI` - API endpoints with no session management

### Practical Example

{% code title="/Application.bx (Root)" %}

```js
class {
    this.name = "PublicWebsite";
    this.sessionTimeout = createTimeSpan( 0, 0, 30, 0 ); // 30 minutes
    this.datasource = "public_db";

    function onApplicationStart() {
        application.maxUsers = 10000;
        application.theme = "light";
    }
}
```

{% endcode %}

{% code title="/admin/Application.bx (Nested)" %}

```js
class {
    this.name = "AdminPanel"; // Different application!
    this.sessionTimeout = createTimeSpan( 0, 0, 5, 0 ); // 5 minutes for security
    this.datasource = "admin_db";

    this.sessionCookie = {
        httpOnly : true,
        secure : true,
        sameSiteMode : "Strict"
    };

    function onApplicationStart() {
        application.maxUsers = 10; // Admin-specific setting
        application.theme = "admin-dark";
    }

    function onRequestStart( string targetPage ) {
        // Admin-specific security
        if ( !session.isAdmin ) {
            relocate( "/admin/login" );
            return false;
        }
        return true;
    }
}
```

{% endcode %}

### Scope Isolation

```js
// In /index.bxm (PublicWebsite app)
application.counter = 100;
echo( application.counter ); // 100

// In /admin/dashboard.bxm (AdminPanel app)
echo( application.counter ); // undefined! Different application scope
application.counter = 500;

// Back in /index.bxm
echo( application.counter ); // Still 100! Isolated
```

### Application Longevity

**Applications live in memory** for the duration specified by `this.applicationTimeout`:

```js
// Default: Never expires (preferred)
this.applicationTimeout = createTimeSpan( 0, 0, 0, 0 );

// Or set a specific timeout if you need auto-restart
this.applicationTimeout = createTimeSpan( 7, 0, 0, 0 ); // 7 days
```

{% hint style="success" %}
**Recommended**: Keep the default `0,0,0,0` (never expires) unless you have a specific need for applications to restart automatically. This provides better performance and stability.
{% endhint %}

**When an application expires:**

1. `onApplicationEnd()` is called
2. Application scope is destroyed
3. Next request triggers `onApplicationStart()` and creates a new application instance

**Manual Control:**

```js
// Force application restart
applicationStop();

// Check if application exists
isDefined( "application" );

// Application-specific cache clearing
cacheRemoveAll( cacheName = "template" );
```

{% hint style="info" %}
**Why you can't "kill" the application scope**: Applications are time-based memory reservations. They expire automatically based on `applicationTimeout` or when explicitly stopped with `applicationStop()`.
{% endhint %}

### Use Cases for Virtual Applications

🎯 **Multi-Tenant SaaS**

```
/tenant1/Application.bx (name: "Tenant1", datasource: "tenant1_db")
/tenant2/Application.bx (name: "Tenant2", datasource: "tenant2_db")
```

🎯 **Microservices Architecture**

```
/users/Application.bx     (name: "UserService")
/orders/Application.bx    (name: "OrderService")
/payments/Application.bx  (name: "PaymentService")
```

🎯 **Environment Separation**

```
/dev/Application.bx  (name: "DevApp", datasource: "dev_db")
/qa/Application.bx   (name: "QAApp", datasource: "qa_db")
/prod/Application.bx (name: "ProdApp", datasource: "prod_db")
```

🎯 **Legacy Migration**

```
/legacy/Application.bx (name: "OldApp", CFML compatibility mode)
/modern/Application.bx (name: "NewApp", pure BoxLang features)
```

{% hint style="success" %}
**Best Practice**: Use descriptive, unique application names. Avoid dynamic names unless you understand the implications for memory management.
{% endhint %}

## 📚 Additional Resources

* **Configuration**: See [Configuration documentation](https://github.com/ortus-boxlang/boxlang-docs/blob/v1.x/getting-started/configuration/README.md) for runtime-level settings
* **Caching**: See [Caching documentation](/boxlang-framework/caching.md) for cache strategies
* **Async**: See [Asynchronous Programming](/boxlang-framework/asynchronous-programming.md) for schedulers and executors
* **Datasources**: See [Datasource configuration](/getting-started/configuration/datasources.md)
* **Java Integration**: See [Java Integration](/boxlang-framework/java-integration.md) for loading Java libraries

{% hint style="info" %}
**CFML Compatibility**: For CFML compatibility reference, see [CFDocs Application.cfc](https://cfdocs.org/application-cfc). BoxLang supports the majority of CFML Application.cfc features with enhanced capabilities.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://boxlang.ortusbooks.com/boxlang-framework/applicationbx.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
