GlassFish, OS X and launchctl

While testing an application with Arquillian, GlassFish and Maven I got launchctl bsexec failed: Inappropriate ioctl for device from OS X. GlassFish cannot be started, failing with lots of org.osgi.framework.BundleExceptions. The stacktraces look like this:

org.osgi.framework.BundleException: Unresolved constraint in bundle org.glassfish.hk2.osgi-adapter [202]: Unable to resolve 202.0: missing requirement [202.0] osgi.wiring.package; (&(osgi.wiring.package=com.sun.enterprise.module)(version>=1.1.0)) [caused by: Unable to resolve 121.0: missing requirement [121.0] osgi.wiring.package; (&(osgi.wiring.package=org.jvnet.hk2.config)(version>=1.1.0)) [caused by: Unable to resolve 37.0: missing requirement [37.0] osgi.wiring.package; (osgi.wiring.package=javax.management)]]
    at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3826)
    at org.apache.felix.framework.Felix.startBundle(Felix.java:1868)
    at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1191)
    at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:295)
    at java.lang.Thread.run(Thread.java:722)
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:487)
    at com.sun.enterprise.glassfish.bootstrap.GlassFishMain.main(GlassFishMain.java:97)
    at com.sun.enterprise.glassfish.bootstrap.ASMain.main(ASMain.java:55)
Caused by: org.glassfish.embeddable.GlassFishException: org.glassfish.embeddable.GlassFishException: No GlassFishRuntime available
    at com.sun.enterprise.glassfish.bootstrap.osgi.OSGiGlassFishRuntimeBuilder.build(OSGiGlassFishRuntimeBuilder.java:164)
    at org.glassfish.embeddable.GlassFishRuntime._bootstrap(GlassFishRuntime.java:157)
    at org.glassfish.embeddable.GlassFishRuntime.bootstrap(GlassFishRuntime.java:110)
    at com.sun.enterprise.glassfish.bootstrap.GlassFishMain$Launcher.launch(GlassFishMain.java:112)
    ... 6 more
Caused by: org.glassfish.embeddable.GlassFishException: No GlassFishRuntime available
    at com.sun.enterprise.glassfish.bootstrap.osgi.OSGiGlassFishRuntimeBuilder.getGlassFishRuntime(OSGiGlassFishRuntimeBuilder.java:202)
    at com.sun.enterprise.glassfish.bootstrap.osgi.OSGiGlassFishRuntimeBuilder.build(OSGiGlassFishRuntimeBuilder.java:162)
    ... 9 more
Error stopping framework: java.lang.NullPointerException
java.lang.NullPointerException
    at com.sun.enterprise.glassfish.bootstrap.GlassFishMain$Launcher$1.run(GlassFishMain.java:203)
launchctl bsexec failed: Inappropriate ioctl for device

Analysis

The problem seems to be a non-Java related error message: launchctl bsexec failed: Inappropriate ioctl for device. Testing with Java 1.7 and 1.8 I got the same result as above. You can test it with different Java versions using /usr/libexec/java_home and specifying -v <ver>:

$ /usr/libexec/java_home -v 1.8.0 --exec java -jar target/glassfish3/glassfish/modules/admin-cli.jar start-domain -t

But with Java 1.6:

$ /usr/libexec/java_home -v 1.6.0 --exec java -jar target/glassfish3/glassfish/modules/admin-cli.jar start-domain -t
Error starting domain domain1.
The server exited prematurely with exit code 1.
Before it died, it produced the following output:

Error: This Java instance does not support a 32-bit JVM.
Please install the desired version.
launchctl bsexec failed: Inappropriate ioctl for device

Hey, wait!

Another test was using sudo to execute with root privileges:

$ sudo /usr/lib exec/java_home -v 1.7.0 --exec java -jar target/glassfish3/glassfish/modules/admin-cli.jar start-domain -t
Successfully started the domain : domain1
domain  Location: /Users/rbe/project/ventplan/ventplan-server/ventplan-api/target/glassfish3/glassfish/domains/domain1
Log File: /Users/rbe/project/ventplan/ventplan-server/ventplan-api/target/glassfish3/glassfish/domains/domain1/logs/server.log
Admin Port: 4848

This also works with Java 1.6!

$ sudo /usr/libexec/java_home -v 1.6.0 --exec java -jar target/glassfish3/glassfish/modules/admin-cli.jar start-domain -t
Successfully started the domain : domain1
domain  Location: /Users/rbe/project/ventplan/ventplan-server/ventplan-api/target/glassfish3/glassfish/domains/domain1
Log File: /Users/rbe/project/ventplan/ventplan-server/ventplan-api/target/glassfish3/glassfish/domains/domain1/logs/server.log
Admin Port: 4848

When GlassFish was launched successfully, the process list shows:

/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin/java
    -cp target/glassfish3/glassfish/modules/glassfish.jar
    -XX:+UnlockDiagnosticVMOptions
    -XX:PermSize=64m -XX:MaxPermSize=192m -XX:NewRatio=2 -Xmx512m
    -client
    -javaagent:target/glassfish3/glassfish/lib/monitor/flashlight-agent.jar
    -Djava.awt.headless=true
    -Djava.endorsed.dirs=target/glassfish3/glassfish/modules/endorsed:target/glassfish3/glassfish/lib/endorsed 
    -Djava.security.policy=target/glassfish3/glassfish/domains/domain1/config/server.policy
    -Djavax.net.ssl.keyStore=target/glassfish3/glassfish/domains/domain1/config/keystore.jks
    -Djavax.net.ssl.trustStore=target/glassfish3/glassfish/domains/domain1/config/cacerts.jks -Dcom.sun.enterprise.security.httpsOutboundKeyAlias=s1as
    -Dosgi.shell.telnet.maxconn=1
    -Dosgi.shell.telnet.ip=127.0.0.1
    -Dosgi.shell.telnet.port=6666
    -Dfelix.fileinstall.disableConfigSave=false 
    -Dfelix.fileinstall.dir=target/glassfish3/glassfish/modules/autostart/ 
    -Dfelix.fileinstall.log.level=2
    -Dfelix.fileinstall.poll=5000
    -Dfelix.fileinstall.bundles.new.start=true
    -Dfelix.fileinstall.bundles.startTransient=true
    -Djdbc.drivers=org.apache.derby.jdbc.ClientDriver
    -DANTLR_USE_DIRECT_CLASS_LOADING=true
    -Dcom.sun.aas.instanceRoot=target/glassfish3/glassfish/domains/domain1
    -Dcom.sun.enterprise.config.config_environment_factory_class=com.sun.enterprise.config.serverbeans.AppserverConfigEnvironmentFactory 
    -Dcom.sun.aas.installRoot=target/glassfish3/glassfish
    -Djava.ext.dirs=/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/lib/ext:/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/jre/lib/ext:target/glassfish3/glassfish/domains/domain1/lib/ext
    -Djava.security.auth.login.config=target/glassfish3/glassfish/domains/domain1/config/login.conf
    -Dgosh.args=--nointeractive 
    -Djava.library.path=target/glassfish3/glassfish/lib:/Users/rbe/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:/Users/rbe 
  com.sun.enterprise.glassfish.bootstrap.ASMain
    -domainname domain1
    -asadmin-args 
    --host,,,localhost,,,--port,,,4848,,,--secure=false,,,--terse=true,,,--echo=false,,,--interactive=true,,,start-domain,,,--verbose=false,,,--debug=false,,,--domaindir,,,target/glassfish3/glassfish/domains,,,domain1
    -instancename server
    -verbose false
    -debug false
    -asadmin-classpath target/glassfish3/glassfish/modules/admin-cli.jar
    -asadmin-classname com.sun.enterprise.admin.cli.AsadminMain
    -upgrade false
    -type DAS
    -domaindir target/glassfish3/glassfish/domains/domain1
    -read-stdin true

Permissions?

So maybe the JVM needs a certain permission to run GlassFish (in a certain mode) (on OS X)?

According to GLASSFISH-15118 and GLASSFISH-12942 this seems to be related to how GF is started on OS X:

$ cat /usr/libexec/StartupItemContext 
#!/bin/sh

unset LAUNCHD_SOCKET

exec launchctl bsexec / "$@"

HTH.

This entry was posted in Software Development, System Administration and tagged , , , . Bookmark the permalink.