diff --git a/docs/03.reference/01.functions/restinitapplication/_arguments/dirPath.md b/docs/03.reference/01.functions/restinitapplication/_arguments/dirPath.md index 9963e7ee0..e9219b28b 100644 --- a/docs/03.reference/01.functions/restinitapplication/_arguments/dirPath.md +++ b/docs/03.reference/01.functions/restinitapplication/_arguments/dirPath.md @@ -1,5 +1,6 @@ Path to the directory to be registered or reset. This folder should contain + - one or more REST enabled CFCs, i.e. with `rest=true` - An `Application.cfc` (if required) \ No newline at end of file diff --git a/docs/03.reference/02.tags/dbinfo/_usageNotes.md b/docs/03.reference/02.tags/dbinfo/_usageNotes.md index 9659e6a61..89492ac34 100644 --- a/docs/03.reference/02.tags/dbinfo/_usageNotes.md +++ b/docs/03.reference/02.tags/dbinfo/_usageNotes.md @@ -2,4 +2,3 @@ Performance tips - Using `type="columns_minimal"` is dramatically faster than `type="columns"` - With `type="table"` using `filter="table"` is also much faster - diff --git a/docs/03.reference/02.tags/pdf/_attributes/action.md b/docs/03.reference/02.tags/pdf/_attributes/action.md index 19d5306e7..0e1549a1f 100644 --- a/docs/03.reference/02.tags/pdf/_attributes/action.md +++ b/docs/03.reference/02.tags/pdf/_attributes/action.md @@ -14,6 +14,8 @@ - setInfo - thumbnail - write +- extractimage (default) +- extractimages (alias for `extractimage`) **Note:** diff --git a/docs/03.reference/02.tags/pdf/tag.md b/docs/03.reference/02.tags/pdf/tag.md index cda7d9d3a..6466233f1 100644 --- a/docs/03.reference/02.tags/pdf/tag.md +++ b/docs/03.reference/02.tags/pdf/tag.md @@ -26,3 +26,4 @@ The following list describes some of the tasks you can perform with the cfpdf ta - Add and remove header/footer from PDF documents - Optimize PDF documents - Extract all the words from the pdf +- Extract images from PDF documents using the `extractimage` action. \ No newline at end of file diff --git a/docs/04.guides/04.cookbooks/02.application-context-set-mapping/page.md b/docs/04.guides/04.cookbooks/02.application-context-set-mapping/page.md index 84e9f6c69..3d9668f21 100644 --- a/docs/04.guides/04.cookbooks/02.application-context-set-mapping/page.md +++ b/docs/04.guides/04.cookbooks/02.application-context-set-mapping/page.md @@ -42,7 +42,7 @@ component { } ``` -In difference to `this.mappings`, `this.componentpaths" and `this.customtagpaths` are taking arrays as input and not structs, because in that case there is not "virtual path" that needs to be defined. +In difference to `this.mappings`, `this.componentpaths` and `this.customtagpaths` are taking arrays as input and not structs, because in that case there is not "virtual path" that needs to be defined. ## Advanced diff --git a/docs/04.guides/11.developing-with-lucee-server/03.operators/page.md b/docs/04.guides/11.developing-with-lucee-server/03.operators/page.md index e4efd0b50..d8ef73390 100644 --- a/docs/04.guides/11.developing-with-lucee-server/03.operators/page.md +++ b/docs/04.guides/11.developing-with-lucee-server/03.operators/page.md @@ -104,7 +104,7 @@ description: Mathematical, Logical, Ternary, Comparison, String and Elvis Operat | --------- | -------------- | ----------- | | EQ | equals | Returns true if operands are equal, e.g. `"A" EQ "A"` is true | | == | equals | Returns true if operands are equal, e.g. `"A" == "A"` is true | -| === | identical | Returns true if operands are the same object in memory, false if they are not, (Note this is different than how JavaScript's `===` operator works). **Lucee 6 === works like javascript, comparing type and value, however, prior to 6.2.3.34, it was senstive to the underlying java types [LDEV-5806](https://luceeserver.atlassian.net/browse/LDEV-5806)** | +| === | identical | Returns true if operands are the same object in memory, false if they are not, (Note this is different than how JavaScript's `===` operator works). **Lucee 6 === works like javascript, comparing type and value, however, prior to 6.2.3.34, it was sensitive to the underlying java types [LDEV-5806](https://luceeserver.atlassian.net/browse/LDEV-5806)** | | NEQ | does not equal | Returns true if operands are not equal, e.g. `"A" NEQ "B"` is true | | \<\> | does not equal | Returns true if operands are not equal, e.g. `"A" <> "B"` is true | | != | does not equal | Returns true if operands are not equal, e.g. `"A" != "B"` is true | diff --git a/docs/04.guides/12.deploying-lucee-server-apps/page.md b/docs/04.guides/12.deploying-lucee-server-apps/page.md index 6e5e164b5..3add24e09 100644 --- a/docs/04.guides/12.deploying-lucee-server-apps/page.md +++ b/docs/04.guides/12.deploying-lucee-server-apps/page.md @@ -105,7 +105,6 @@ You can pre warm a lucee installation, by setting the env var `LUCEE_ENABLE_WARM Lucee Docker images are already pre-warmed and Lucee 6.2 includes several improvements which make deployment faster. - ## Admin and Docs extensions You will see extensions, Lucee Admin and Lucee Docs, these simply install mappings to make them available. The admin is tightly coupled to the Lucee Version, so they aren't separately deployed diff --git a/docs/recipes/breaking-changes-6-2.md b/docs/recipes/breaking-changes-6-2.md index 5556870eb..a43c49288 100644 --- a/docs/recipes/breaking-changes-6-2.md +++ b/docs/recipes/breaking-changes-6-2.md @@ -111,7 +111,7 @@ Workaround, create an Application.cfc which extends the parent Application.cfc [LDEV-5323](https://luceeserver.atlassian.net/browse/LDEV-5323) -## Strict Equality Operator was senstive to underlying java types +## Strict Equality Operator was sensitive to underlying java types Lucee 6 improved the `===` operator to compare type and value, but was checking only the underlying java type, rather than cfml type, so numbers might fail diff --git a/docs/recipes/cfschedule-bulk-update.md b/docs/recipes/cfschedule-bulk-update.md index e18e4acc7..ff926f6a1 100644 --- a/docs/recipes/cfschedule-bulk-update.md +++ b/docs/recipes/cfschedule-bulk-update.md @@ -1,6 +1,6 @@ -## Efficently and reliably updating scheduled tasks in a single operation +## Efficiently and reliably updating scheduled tasks in a single operation Using the [[tag-schedule]] to update all tasks on application start has always been a bit slow, as each update reloads the config which is slow when updating many tasks. @@ -31,7 +31,7 @@ Note, this approach only works reliably since 6.2.3.16, as the config import / m ### Updating tasks in a single transaction -An alternative and far more efficent approach is to +An alternative and far more efficient approach is to 1. Extract the **scheduledTasks** from `.CFConfig.json`, 2. Check and modify the array of tasks if needed (i.e. track changes) @@ -76,7 +76,7 @@ Loop over the array and modify it as needed. ### Tip: avoid updates when there is no change -It's good to avoid updating the config if there is no change, but not so important when using this efficent approach. +It's good to avoid updating the config if there is no change, but not so important when using this efficient approach. An easy way is to simply compare the source tasks array with the updated tasks array. diff --git a/docs/recipes/hooks-and-monitors.md b/docs/recipes/hooks-and-monitors.md index 7a5b3c9ea..d08ceb6e9 100644 --- a/docs/recipes/hooks-and-monitors.md +++ b/docs/recipes/hooks-and-monitors.md @@ -321,6 +321,7 @@ You can define monitors directly in your `.CFConfig.json` configuration file und ``` **Configuration Properties:** + - `name`: Unique identifier for the monitor (required) - `type`: Monitor type - `action`, `request`, or `interval` (required) - `class`: Full Java class name (required unless using component) @@ -332,6 +333,7 @@ You can define monitors directly in your `.CFConfig.json` configuration file und - `async`: Run request monitors asynchronously (optional, request monitors only, default: false) **Class Definition Resolution Order:** + 1. **OSGi Bundle** - If `bundleName` is provided 2. **Maven Dependency** - If `maven` is provided 3. **CFML Component** - If `component` is provided (and `class` is null) @@ -412,6 +414,7 @@ public class MyActionMonitor implements ActionMonitor { ### Use Cases Action monitors are ideal for: + - Database query performance tracking - Lock contention analysis - Mail delivery monitoring @@ -488,6 +491,7 @@ public class MyRequestMonitor implements RequestMonitor { ### Use Cases Request monitors are ideal for: + - Application performance monitoring (APM) - Error rate tracking - User behavior analysis @@ -566,6 +570,7 @@ public class MyIntervalMonitor implements IntervallMonitor { ### Use Cases Interval monitors are ideal for: + - System resource monitoring - Memory leak detection - Performance baseline establishment @@ -633,16 +638,19 @@ When implementing hooks and monitors, consider these security aspects: ## Common Issues **Hook Not Loading** + - Verify class name and path are correct - Check bundle/Maven dependencies are available - Review Lucee logs for error messages **Monitor Not Triggering** + - Ensure monitoring is enabled in `.CFConfig.json` - Check that the monitor interface is implemented correctly - Verify the extension manifest syntax is valid **Performance Issues** + - Keep monitor logic lightweight - Use asynchronous processing for expensive operations - Implement proper error handling to prevent monitor failures diff --git a/docs/recipes/query-result-threshold.md b/docs/recipes/query-result-threshold.md index 8699d27ae..f5669a415 100644 --- a/docs/recipes/query-result-threshold.md +++ b/docs/recipes/query-result-threshold.md @@ -32,11 +32,13 @@ This feature provides early warning when queries return unexpectedly large datas Query result logging is configured using a single environment variable or system property: **Environment Variable:** + ```bash LUCEE_QUERY_RESULT_THRESHOLD=100000 ``` **System Property:** + ```bash -Dlucee.query.result.threshold=100000 ``` @@ -157,10 +159,10 @@ When large result sets are logged: 2. Check that queries actually exceed the threshold 3. Ensure `warn` level logging is enabled for the `datasource` category - ### False Positives If logging captures expected large result sets: + - Adjust the threshold higher - Use different thresholds for different environments - Consider the business logic requirements diff --git a/docs/recipes/thread-dump-startup.md b/docs/recipes/thread-dump-startup.md index d6d537be3..68db665b0 100644 --- a/docs/recipes/thread-dump-startup.md +++ b/docs/recipes/thread-dump-startup.md @@ -169,6 +169,7 @@ function analyzeThreadDump(path, threadName) { ``` This function provides: + - **Thread filtering**: Focus on specific threads by name (case-insensitive partial matching) - **Relative timing**: Shows elapsed time from the first captured snapshot - **Stack trace limiting**: Displays only the top stack frames for better readability diff --git a/docs/technical-specs/hooks.yaml b/docs/technical-specs/hooks.yaml index ddc239001..f7c0fb33c 100644 --- a/docs/technical-specs/hooks.yaml +++ b/docs/technical-specs/hooks.yaml @@ -13,24 +13,24 @@ configuration: property: "startupHooks" format: "Array of objects" schema: - class: + class: type: "string" required: true description: "Full Java class name" - bundleName: + bundleName: type: "string" required: false description: "OSGi bundle symbolic name" - bundleVersion: + bundleVersion: type: "string" required: false description: "OSGi bundle version" - maven: + maven: type: "string" required: false description: "Maven coordinates (groupId:artifactId:version)" alternative_to: ["bundleName", "bundleVersion"] - component: + component: type: "string" required: false description: "CFML component path" @@ -59,7 +59,7 @@ constructor_resolution: parameter_type: "lucee.runtime.config.Config" actual_type: "ConfigServer instance" detection: "Reflector.getConstructor(clazz, new Class[]{Config.class})" - + fallback: signature: "public ClassName()" usage: "ClassUtil.loadInstance(clazz)" @@ -70,17 +70,17 @@ class_loading: method: "ClassUtil.loadClassByBundle()" parameters: - "className" - - "bundleName" + - "bundleName" - "version (OSGi Version object)" - "identification" - "bundleDirectories" - "versionOnlyMattersWhenDownloading" - + maven_dependency: condition: "maven is not null" method: "config.getRPCClassLoader().loadClass()" settings: "JavaSettingsImpl.getInstance(config, getMaven())" - + standard_classpath: condition: "fallback" method: "ClassUtil.loadClass(ThreadLocalPageContext.getRPCClassLoader())" @@ -96,7 +96,7 @@ instance_management: recommended: true static_field: "private static ClassName instance = null" error_field: "private static RuntimeException re" - access_method: + access_method: signature: "public static ClassName getInstance() throws PageException" error_handling: "Throw PageException with initCause if initialization failed" @@ -106,7 +106,7 @@ lifecycle_methods: web_context_iteration: "configServer.getConfigWebs()" context_filtering: "cw != null && cw.getServletContext() != null" cli_exclusion: "!(cw.getServletContext() instanceof lucee.cli.servlet.ServletContextImpl)" - + finalization: method: "public void finalize()" trigger: "Hook replacement or server shutdown" @@ -126,7 +126,7 @@ error_handling: storage: "Store RuntimeException in static field" propagation: "Re-throw from constructor" access: "Include as initCause in getInstance() PageException" - + runtime_errors: logging: "ConfigBase.log(config, log, throwable)" continuation: "Process continues with remaining hooks" @@ -136,7 +136,7 @@ implementation_details: loading_trigger: "During ConfigServerImpl construction" thread_safety: "Not required - sequential loading" replacement_detection: "cd.equals(existing.cd)" - + system_integration: cfml_engine: "CFMLEngineFactory.getInstance()" creation_util: "eng.getCreationUtil()" @@ -148,12 +148,12 @@ common_patterns: servlet_container: "ServletContext attributes" jndi_binding: "Context.bind()" system_properties: "System.getProperties().put()" - + resource_initialization: connection_pools: "DataSource configuration" thread_pools: "ExecutorService creation" cache_managers: "Cache provider setup" - + web_context_management: concurrent_map: "Map contexts" context_id: "cw.getIdentification().getId()" @@ -162,22 +162,22 @@ common_patterns: dependencies: required: - name: "lucee-core" - classes: + classes: - "lucee.runtime.config.Config" - "lucee.runtime.config.ConfigServer" - "lucee.runtime.config.ConfigWeb" - name: "lucee.loader" classes: - "lucee.loader.engine.CFMLEngineFactory" - + optional: - name: "osgi-framework" purpose: "Bundle class loading" - - name: "maven-resolver" + - name: "maven-resolver" purpose: "Maven dependency resolution" logging: initialization: "System.out.println() for startup messages" errors: "System.err.println() + printStackTrace()" web_context_registration: "Log context ID and servlet path" - replacement: "Log when hooks are replaced" \ No newline at end of file + replacement: "Log when hooks are replaced" diff --git a/docs/technical-specs/monitors.yaml b/docs/technical-specs/monitors.yaml index 08a1dbc56..c28844794 100644 --- a/docs/technical-specs/monitors.yaml +++ b/docs/technical-specs/monitors.yaml @@ -76,16 +76,16 @@ monitor_types: base_interface: "lucee.runtime.monitor.Monitor" trigger: "Synchronous during specific operations" thread_context: "Operation execution thread" - + operations: - query: + query: call: "((ConfigWebPro)pageContext.getConfig()).getActionMonitorCollector().log(pageContext, 'query', 'Query', executionTime, queryResult)" lock: call: "((ConfigWebPro)pc.getConfig()).getActionMonitorCollector().log(pageContext, 'lock', 'Lock', executionTime, lockName + ':' + timeoutInMillis)" mail: call: "((ConfigWebPro)config).getActionMonitorCollector().log(config, 'mail', 'Mail', executionTime, properties)" cache: "Cache operations" - + methods: log_request: signature: "void log(PageContext pc, String type, String label, long executionTime, Object data)" @@ -96,7 +96,7 @@ monitor_types: label: "Operation label" executionTime: "Duration in milliseconds" data: "Operation-specific data" - + log_background: signature: "void log(ConfigWeb config, String type, String label, long executionTime, Object data)" context: "Outside HTTP request context" @@ -106,7 +106,7 @@ monitor_types: label: "Operation label" executionTime: "Duration in milliseconds" data: "Operation-specific data" - + get_data: signature: "Query getData(Map arguments)" purpose: "Return collected data for reporting" @@ -121,7 +121,7 @@ monitor_types: trigger: "End of each HTTP request" thread_context: "Request processing thread" async_support: true - + methods: log: signature: "void log(PageContext pc, boolean error)" @@ -129,7 +129,7 @@ monitor_types: parameters: pc: "Page context with request data" error: "True if request resulted in error" - + get_data: signature: "Query getData(ConfigWeb config, Map arguments)" scope: "Single web context data" @@ -144,13 +144,13 @@ monitor_types: trigger: "Timer-based (default 5000ms)" thread_context: "Dedicated interval monitoring thread" request_context: false - + methods: log: signature: "void log()" timing: "Called at regular intervals" context: "No PageContext available" - + get_data: signature: "Query getData(Map arguments)" scope: "System-wide interval data" @@ -168,11 +168,11 @@ base_interface: config: "Web configuration instance" name: "Monitor name from configuration" arguments: "Additional configuration parameters" - + get_name: signature: "String getName()" purpose: "Return monitor identifier" - + is_enabled: signature: "boolean isEnabled()" purpose: "Runtime enable/disable check" @@ -180,21 +180,21 @@ base_interface: implementation_details: loading_method: "ConfigFactoryImpl.loadMonitors()" loading_context: "Server configuration initialization" - + constructor_resolution: with_config: signature: "public ClassName(ConfigServer configServer)" detection: "Reflector.getConstructorInstance()" - + default: signature: "public ClassName()" fallback: "ClassUtil.newInstance(clazz)" - + wrapper_classes: action: "ActionMonitorWrap for non-ActionMonitor objects" request: "RequestMonitorWrap for non-RequestMonitor objects" interval: "IntervallMonitorWrap for non-IntervallMonitor objects" - + async_implementation: wrapper: "AsyncRequestMonitor" condition: "async=true in configuration" @@ -206,12 +206,12 @@ storage: factory: "ActionMonitorFactory.getActionMonitorCollector()" storage_method: "configServer.setActionMonitorCollector()" access: "((ConfigWebPro)config).getActionMonitorCollector()" - + request_monitors: type: "RequestMonitor[] array" storage_method: "configServer.setRequestMonitors()" wrapper: "RequestMonitorProImpl" - + interval_monitors: type: "IntervallMonitor[] array" storage_method: "configServer.setIntervallMonitors()" @@ -223,7 +223,7 @@ cfml_integration: types: ["action", "request", "interval"] return_type: "Query" implementation: "Calls monitor.getData(arguments)" - + get_monitoring_info: signature: "getMonitoringInfo()" return_type: "Struct" @@ -233,7 +233,7 @@ error_handling: monitor_failure: logging: "LogUtil.logGlobal(config, Log.LEVEL_INFO, class, message)" continuation: "Processing continues with remaining monitors" - + runtime_exceptions: action_monitors: "Log error, continue operation" request_monitors: "Log error, continue request processing" @@ -244,17 +244,17 @@ threading: execution: "Synchronous in operation thread" performance_impact: "Direct impact on operation timing" recommendations: "Keep implementations lightweight" - + request_monitors: synchronous: execution: "End of request thread" blocking: "Delays request completion" - + asynchronous: wrapper: "AsyncRequestMonitor" execution: "Background thread pool" impact: "No request delay" - + interval_monitors: thread: "Dedicated system monitoring thread" isolation: "Separate from request processing" @@ -262,13 +262,13 @@ threading: type_constants: action: "Monitor.TYPE_ACTION" - request: "IntervallMonitor.TYPE_REQUEST" + request: "IntervallMonitor.TYPE_REQUEST" interval: "IntervallMonitor.TYPE_INTERVAL" class_definitions: resolution_order: "OSGi bundle > Maven > Standard classpath" loading: "ClassDefinition.getClazz()" - + formats: osgi: bundleName: "OSGi symbolic name" @@ -283,12 +283,12 @@ logging: level: "INFO" method: "LogUtil.logGlobal()" message: "loaded {type} monitor [{className}]" - + monitor_initialization: - level: "INFO" + level: "INFO" method: "LogUtil.logGlobal()" message: "initialize {type} monitor [{className}]" - + runtime_errors: method: "LogUtil.logGlobal(config, className, throwable)" level: "ERROR" @@ -301,9 +301,9 @@ dependencies: - "lucee.runtime.config.ConfigWeb" - "lucee.runtime.PageContext" - "lucee.runtime.type.Query" - + optional: - name: "osgi-framework" purpose: "Bundle class loading" - name: "servlet-api" - purpose: "HTTP request monitoring" \ No newline at end of file + purpose: "HTTP request monitoring"