Quick Apache Karaf Integration (Windows)

Apache Karaf OSGi Runtime 4.4.x Integration (Windows)

This page describes the steps to get up and running quickly with Apache Karaf 4.4.11. Other versions should work in a similar way.

Karaf has implemented a way to run with the Java Service Wrapper for quite some time, but it currently uses a very outdated version that lacks support for many modern operating systems and architectures. The Wrapper has evolved significantly since then, and upgrading is highly recommended. See the default Service Wrapper Instructions if you are interested, but we will not be using them here. Following those instructions would add extra files that could be confusing.

Download Karaf

Download Karaf OSGi Runtime as a zip file from their Download Page. We will be working with apache-karaf-4.4.11.zip.

Extract the archive to obtain an apache-karaf-4.4.11 directory, and optionally rename it to whatever you prefer to work with.

Download Wrapper

The following steps are designed to work with version 3.7.0 of the Java Service Wrapper. Using earlier versions is possible, but will likely require some changes.

Decide which edition to use (Professional, Standard, or Community), and select the target platform, bitness, and architecture. Then download the installer or archive and install or extract it. We will assume you are using the Professional 64-bit Edition on Windows x86.

Wrapper Integration

To ease the placement of required Wrapper files, create the following PowerShell script in your extracted apache-karaf-4.4.11 directory as updateWrapper.ps1. Update the location where you installed or extracted the Wrapper above.

$WRAPPER_HOME = "../wrapper-windows-x86-64-3.7.0-pro"
$KARAF_HOME = "."
$WRAPPER_SCRIPT = "karaf-service.bat"
$WRAPPER_SCRIPT_PATH = "$KARAF_HOME/bin/$WRAPPER_SCRIPT"

[void](New-Item -ItemType Directory -Force -Path "$KARAF_HOME/lib/wrapper")
if (Test-Path "$WRAPPER_HOME/lang" -PathType Container) {
    Copy-Item -Path "$WRAPPER_HOME/lang/wrapper_*.mo" -Destination "$KARAF_HOME/lib/wrapper/"
    Copy-Item -Path "$WRAPPER_HOME/lang/wrapperjni_*.mo" -Destination "$KARAF_HOME/lib/wrapper/"
}
if (Test-Path "$WRAPPER_HOME/src/conf/wrapper-license-time.conf" -PathType Leaf) {
    Copy-Item -Path "$WRAPPER_HOME/src/conf/wrapper-license-time.conf" -Destination "$KARAF_HOME/etc/wrapper-license.conf"
}

Copy-Item -Path "$WRAPPER_HOME/bin/wrapper.exe" -Destination "$KARAF_HOME/bin/wrapper.exe" -Force
Copy-Item -Path "$WRAPPER_HOME/lib/wrapper.jar" -Destination "$KARAF_HOME/lib/wrapper/" -Force
Copy-Item -Path "$WRAPPER_HOME/lib/wrapper.dll" -Destination "$KARAF_HOME/lib/wrapper/" -Force
Copy-Item -Path "$WRAPPER_HOME/src/bin/AppCommand.bat.in" -Destination "$WRAPPER_SCRIPT_PATH" -Force

(Get-Content $WRAPPER_SCRIPT_PATH) `
    -replace 'set _WRAPPER_CONF="\.\./conf/%_WRAPPER_BASE%.conf"', 'set _WRAPPER_CONF="../etc/%_WRAPPER_BASE%.conf"' |
    Set-Content $WRAPPER_SCRIPT_PATH

Run the script:

./updateWrapper.ps1

注意

If PowerShell reports that script execution is disabled, run:

powershell.exe -ExecutionPolicy Bypass -File .\updateWrapper.ps1

This bypass applies only to that invocation and does not modify your PowerShell configuration.


The configuration uses Integration Method 1.

注意

- The JAVA_HOME must be set, but will default to the system environment if defined there. Karaf 4.4.x series requires a minimum of Java 11 be specified.

- The KARAF_VERSION must match the specific version of Karaf being run.

Create the Wrapper configuration file as etc/wrapper.conf with the following content:

@encoding=UTF-8
# The configuration file must begin with a line declaring its encoding.

# Default mode for file inclusions
@include.default_mode=required

# Include file problems can be debugged by removing '#' at the beginning
#  of the following line:
#@include.debug

#********************************************************************
# Wrapper License Properties (Ignored by Community Edition)
#********************************************************************
# Professional and Standard Editions of the Wrapper require a valid
#  License Key to start.  Licenses can be purchased or a trial license
#  requested on the following pages:
# https://wrapper.tanukisoftware.com/purchase
# https://wrapper.tanukisoftware.com/trial

# The Wrapper will look for either of the following optional files for a
#  valid License Key.  License Key properties can optionally be included
#  directly in this configuration file.
@include.optional %WRAPPER_CONF_DIR%/wrapper-license.conf
@include.optional %WRAPPER_CONF_DIR%/wrapper-license-%WRAPPER_HOST_NAME%.conf

# The following property will output information about which License Key(s)
#  are being found, and can aid in resolving any licensing problems.
#wrapper.license.debug=TRUE

#********************************************************************
# Environment
#********************************************************************
set.default.JAVA_HOME=(SetMe)
set.KARAF_VERSION=4.4.11
set.KARAF_HOME=%WRAPPER_BIN_DIR%/..
set.KARAF_BASE=%WRAPPER_BIN_DIR%/..
set.KARAF_DATA=%KARAF_BASE%/data
set.KARAF_ETC=%KARAF_BASE%/etc
set.KARAF_LOG=%KARAF_BASE%/data/log

# Change the working dir used by java so Karaf is in its expected location.
#  Setting KARAF_BASE relative to the fixed WRAPPER_BIN_DIR location helps make their meaning clear and avoid confusion when changing the working dir.
wrapper.working.dir=%KARAF_BASE%

#********************************************************************
# Wrapper Localization
#********************************************************************
# Specify the language and locale which the Wrapper should use.
#wrapper.lang=en_US # en_US or ja_JP

# Specify the location of the language resource files (*.mo).
wrapper.lang.folder=%KARAF_HOME%/lib/wrapper

#********************************************************************
# Wrapper Java Properties
#********************************************************************
# Java Application
wrapper.java.command=%JAVA_HOME%/bin/java

# Tell the Wrapper to log the full generated Java command line.
#wrapper.java.command.loglevel=INFO

# Wrapper Jar file
wrapper.jarfile=%KARAF_HOME%/lib/wrapper/wrapper.jar

# Java Version control
wrapper.java.version.output=true
wrapper.java.version.min=11
#wrapper.java.version.max=

# Log level for notices about missing Java Classpath entries.
wrapper.java.classpath.missing.loglevel=WARN

# Java Classpath.  Add class path elements as needed starting from 1
wrapper.java.classpath.1=%KARAF_BASE%/lib/boot/*.jar
wrapper.java.classpath.2=%KARAF_BASE%/lib/jdk9plus/*.jar

# Java Modulepath. (Requires Java 9 or above)
#  Add module path elements as needed starting from 1
#wrapper.java.module_path.1=

# Java Module list. (Requires Java 9 or above)
#  Add module names as needed starting from 1
#wrapper.java.module.1=

# Java Library Path (location of wrapper.dll or libwrapper.so)
wrapper.java.library.path.1=%KARAF_HOME%/lib/wrapper

# Java Bits.  On applicable platforms, tells the JVM to run in 32 or 64-bit mode.
wrapper.java.additional.auto_bits=TRUE

# Java Additional Parameters

#  Module configuration
wrapper.java.additional.1=--add-reads=java.xml=java.logging
wrapper.java.additional.2=--add-exports=java.base/org.apache.karaf.specs.locator=java.xml,ALL-UNNAMED
wrapper.java.additional.3=--patch-module java.base=%KARAF_HOME%/lib/endorsed/org.apache.karaf.specs.locator-%KARAF_VERSION%.jar
wrapper.java.additional.4=--patch-module java.xml=%KARAF_HOME%/lib/endorsed/org.apache.karaf.specs.java.xml-%KARAF_VERSION%.jar
wrapper.java.additional.5=--add-opens java.base/java.security=ALL-UNNAMED
wrapper.java.additional.6=--add-opens java.base/java.net=ALL-UNNAMED
wrapper.java.additional.7=--add-opens java.base/java.lang=ALL-UNNAMED
wrapper.java.additional.8=--add-opens java.base/java.util=ALL-UNNAMED
wrapper.java.additional.9=--add-opens java.naming/javax.naming.spi=ALL-UNNAMED
wrapper.java.additional.10=--add-opens java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED
wrapper.java.additional.11=--add-exports=java.base/sun.net.www.protocol.file=ALL-UNNAMED
wrapper.java.additional.12=--add-exports=java.base/sun.net.www.protocol.ftp=ALL-UNNAMED
wrapper.java.additional.13=--add-exports=java.base/sun.net.www.protocol.http=ALL-UNNAMED
wrapper.java.additional.14=--add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED
wrapper.java.additional.15=--add-exports=java.base/sun.net.www.protocol.jar=ALL-UNNAMED
wrapper.java.additional.16=--add-exports=java.base/sun.net.www.content.text=ALL-UNNAMED
wrapper.java.additional.17=--add-exports=jdk.xml.dom/org.w3c.dom.html=ALL-UNNAMED
wrapper.java.additional.18=--add-exports=jdk.naming.rmi/com.sun.jndi.url.rmi=ALL-UNNAMED
wrapper.java.additional.19=--add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED
wrapper.java.additional.20=--add-exports=java.security.sasl/com.sun.security.sasl=ALL-UNNAMED
wrapper.java.additional.21=--add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED 

#  Additional java configuration
wrapper.java.additional.30=-Djava.io.tmpdir=%KARAF_DATA%/tmp
wrapper.java.additional.31=-Djava.util.logging.config.file=%KARAF_ETC%/java.util.logging.properties

# Uncomment to enable jmx
#wrapper.java.additional.40=-Dcom.sun.management.jmxremote.port=1616
#wrapper.java.additional.41=-Dcom.sun.management.jmxremote.authenticate=false
#wrapper.java.additional.42=-Dcom.sun.management.jmxremote.ssl=false

# Uncomment to enable YourKit profiling
#wrapper.java.additional.43=-Xrunyjpagent

# Uncomment to enable remote debugging
#wrapper.java.additional.44=-Xdebug -Xnoagent -Djava.compiler=NONE
#wrapper.java.additional.45=-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005

# Initial Java Heap Size (in MB)
#wrapper.java.initmemory=3

# Maximum Java Heap Size (in MB)
wrapper.java.maxmemory=512

# Application System Properties passed via the backend.
#  Core Java System Properties must be passed using wrapper.java.additional.<n>.
wrapper.app.property.1=karaf.instances=%KARAF_HOME%/instances
wrapper.app.property.2=karaf.home=%KARAF_HOME%
wrapper.app.property.3=karaf.base=%KARAF_BASE%
wrapper.app.property.4=karaf.data=%KARAF_DATA%
wrapper.app.property.5=karaf.etc=%KARAF_ETC%
wrapper.app.property.6=karaf.log=%KARAF_LOG%
wrapper.app.property.7=karaf.restart.jvm.supported=true
wrapper.app.property.10=karaf.startLocalConsole=false
wrapper.app.property.11=karaf.startRemoteShell=true

# Java Main class.  This class must implement the WrapperListener interface
#  or guarantee that the WrapperManager class is initialized.
#  Helper classes are provided to do this for you.
#  See the following page for details:
#  https://wrapper.tanukisoftware.com/doc/english/integrate.html
#wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperStartStopApp
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

# Application parameters.
#  Pass parameters via the backend instead of the command line.
#wrapper.app.parameter.backend=TRUE

#  Add parameters as needed starting from 1
wrapper.app.parameter.1=org.apache.karaf.main.Main
wrapper.app.parameter.2=start

#********************************************************************
# Wrapper Logging Properties
#********************************************************************
# Enables Debug output from the Wrapper.
# wrapper.debug=TRUE

# Format of output for the console.  (See docs for formats)
wrapper.console.format=PM

# Log Level for console output.  (See docs for log levels)
wrapper.console.loglevel=INFO

# Log file to use for Wrapper output logging.
wrapper.logfile=%KARAF_LOG%/wrapper.log

# Format of output for the log file.  (See docs for formats)
wrapper.logfile.format=LPTM

# Log Level for log file output.  (See docs for log levels)
wrapper.logfile.loglevel=INFO

# Roll mode of the log file.
#  SIZE_OR_WRAPPER causes the file to be rolled whenever its size exceeds the
#  value defined by wrapper.logfile.maxsize, or whenever the Wrapper is
#  launched.
wrapper.logfile.rollmode=SIZE_OR_WRAPPER

# Maximum size that the log file will be allowed to grow to before
#  the log is rolled. Size is specified in bytes.  The default value
#  of 0 disables log rolling.  May abbreviate with the 'k' (kb) or
#  'm' (mb) suffixes.  For example: 10m = 10 megabytes.
wrapper.logfile.maxsize=10m

# Maximum number of rolled log files which will be allowed before old
#  files are deleted.  The default value of 0 implies no limit.
wrapper.logfile.maxfiles=9

# Log Level for sys/event log output.  (See docs for log levels)
wrapper.syslog.loglevel=NONE

#********************************************************************
# Wrapper General Properties
#********************************************************************
# Allow for the use of non-contiguous numbered properties
wrapper.ignore_sequence_gaps=TRUE

# Do not start if the pid file already exists.
wrapper.pidfile.strict=TRUE

# Title to use when running as a console
wrapper.console.title=Apache Karaf

#********************************************************************
# Wrapper JVM Checks
#********************************************************************
# Detect DeadLocked Threads in the JVM. (Requires Standard Edition)
wrapper.check.deadlock=TRUE
wrapper.check.deadlock.interval=60
wrapper.check.deadlock.action=RESTART
wrapper.check.deadlock.output=FULL

# Out Of Memory detection.
#  Ignore -verbose:class output to avoid false positives.
wrapper.filter.trigger.1000=[Loaded java.lang.OutOfMemoryError
wrapper.filter.action.1000=NONE
#  Ignore -Xlog:class+load=level output to avoid false positives.
wrapper.filter.trigger.1001=[class,load] java.lang.OutOfMemoryError
wrapper.filter.action.1001=NONE
# (Simple match)
wrapper.filter.trigger.1002=java.lang.OutOfMemoryError
# (Only match text in stack traces if -XX:+PrintClassHistogram is being used.)
#wrapper.filter.trigger.1002=Exception in thread "*" java.lang.OutOfMemoryError
#wrapper.filter.allow_wildcards.1002=TRUE
wrapper.filter.action.1002=RESTART
wrapper.filter.message.1002=The JVM has run out of memory.

#********************************************************************
# Wrapper Email Notifications. (Requires Professional Edition)
#********************************************************************
# Common Event Email settings.
#wrapper.event.default.email.debug=TRUE
#wrapper.event.default.email.smtp.host=<SMTP_Host>
#wrapper.event.default.email.smtp.port=25
#wrapper.event.default.email.subject=[%WRAPPER_HOSTNAME%:%WRAPPER_NAME%:%WRAPPER_EVENT_NAME%] Event Notification
#wrapper.event.default.email.sender=<Sender email>
#wrapper.event.default.email.recipient=<Recipient email>

# Configure the log attached to event emails.
#wrapper.event.default.email.maillog=ATTACHMENT
#wrapper.event.default.email.maillog.lines=50
#wrapper.event.default.email.maillog.format=LPTM
#wrapper.event.default.email.maillog.loglevel=INFO

# Enable specific event emails.
#wrapper.event.wrapper_start.email=TRUE
#wrapper.event.jvm_prelaunch.email=TRUE
#wrapper.event.jvm_start.email=TRUE
#wrapper.event.jvm_started.email=TRUE
#wrapper.event.jvm_deadlock.email=TRUE
#wrapper.event.jvm_stop.email=TRUE
#wrapper.event.jvm_stopped.email=TRUE
#wrapper.event.jvm_restart.email=TRUE
#wrapper.event.jvm_failed_invocation.email=TRUE
#wrapper.event.jvm_max_failed_invocations.email=TRUE
#wrapper.event.jvm_kill.email=TRUE
#wrapper.event.jvm_killed.email=TRUE
#wrapper.event.jvm_unexpected_exit.email=TRUE
#wrapper.event.wrapper_stop.email=TRUE

# Specify custom mail content
wrapper.event.jvm_restart.email.body=The JVM was restarted.\n\nPlease check on its status.\n

#********************************************************************
# Wrapper Secure File Properties
#********************************************************************
# To enforce the principle of least privilege for files containing
#  sensitive data, the Wrapper requires that all permissions granted
#  to these files be explicitly allowed in the configuration.
#  Please read the documentation for the full list of properties.

# Allow specific accounts or groups on Windows.
#wrapper.secure_file.check.windows.allowed_account.1=NT AUTHORITY\SYSTEM
#wrapper.secure_file.check.windows.allowed_account.2=BUILTIN\Administrators

# Allow specific groups on Unix systems.
#wrapper.secure_file.check.unix.allowed_group.1=<Group_Of_Users>

# Additional files to check for permissions (Requires Standard Edition)
#wrapper.secure_file.additional.1=<Secured_File>

#********************************************************************
# Wrapper Windows Service Properties
#********************************************************************
# WARNING - Do not modify any of these properties when an application
#  using this configuration file has been installed as a service.
#  Please uninstall the service before modifying this section.
#  The service can then be reinstalled.

# Name of the service
wrapper.name=karaf

# Display name of the service
wrapper.displayname=Karaf

# Description of the service
wrapper.description=Apache Karaf OSGi Runtime

# Service dependencies.  Add dependencies as needed starting from 1
wrapper.ntservice.dependency.1=

# Mode in which the service is installed.
#  AUTO_START, DELAY_START (Requires Standard Edition) or DEMAND_START
wrapper.ntservice.starttype=AUTO_START

# Account to use when running the service.
#  The default blank value will use LocalSystem, which is highly privileged
#  account on Windows. Please read the documentation page for this property to
#  learn about other account types that can be used.
wrapper.ntservice.account=

# Allow the current user to perform certain actions without being prompted for
#  administrator credentials. (Requires Professional Edition)
#wrapper.ntservice.permissions.1.account=CURRENT_USER
#wrapper.ntservice.permissions.1.allow=START, STOP, PAUSE_RESUME

注意

If you are using the Standard or Professional Edition, then a default 15 minute license will have been copied as etc/wrapper-license.conf. You will need to update with a trial, server, or development license to run for longer than that.

Running

When running with the Wrapper, you will not have access to the Karaf console directly because it will be running in server mode. So you will need to connect to Karaf via the client or directly via SSH. To do so, you will first need to set up at least one admin user in the etc/users.properties file. You just need to uncomment the karaf user and admingroup. We recommend changing the password to something secure. As with everything here, you will likely need to tune your configuration for maximum security.


To run within a console:

  • Execute: bin/karaf-service.bat console

To run as a Windows Service:

  • Install the service with: bin/karaf-service.bat install

  • Then start the service with: bin/karaf-service.bat start

  • Stop the service with: bin/karaf-service.bat stop

  • Uninstall the service with: bin/karaf-service.bat remove

For a list of available commands:

  • Run: bin/karaf-service.bat

When Karaf runs in server mode, it does not output anything useful to its console. This means that the Wrapper's log file will only contain low-level Java errors or output. Most Karaf log output needs to be viewed in data/log/karaf.log, while the Wrapper's log file can be found in data/log/wrapper.log.

Follow-Up Questions

If you are a Karaf power user and have suggestions for improving this document, please let us know at support@tanukisoftware.com.

We would of course be interested in learning of any way to enable some or all console output so that information could be logged to the wrapper.log file. This would allow the Wrapper's trigger system to react to application output, send alert emails, etc.