GlassFish 付属の JavaDB(Derby) 10.9.1.0 を Java7u51 で起動する
Java7u51の Socket Permission の変更によって49152未満のポート番号でソケットを Listen する場合には明示的にパーミッションを与えることが必要になったようです。
参考: Java™ SE Development Kit 7 Update 51 Release Notes
このため、デフォルトでTCP ポート1527でリッスンする JavaDB も以下のようなエラーを吐いて起動できなくなりました。
C:\glassfish4\glassfish\bin>asadmin start-database Starting database in Network Server mode on host 0.0.0.0 and port 1527. Unable to start database. Please check log in C:\glassfish4\glassfish\databases\derby.log. Command start-database failed.
実際のログファイルの中はこんな感じ
Sun Feb 02 06:29:10 UTC 2014: Booting Derby version The Apache Software Foundation - Apache Derby - 10.9.1.0 - (1344872): instance a816c00e-0143-f149-323a-00000c6e8579 on database directory C:\glassfish4\glassfish\databases\dnd_db with class loader sun.misc.Launcher$AppClassLoader@1860045 Loaded from file:/C:/glassfish4/javadb/lib/derby.jar java.vendor=Oracle Corporation java.runtime.version=1.7.0_51-b13 user.dir=C:\glassfish4\javadb\bin derby.system.home=C:\glassfish4\glassfish\databases Database Class Loader started - derby.database.classpath='' Sun Feb 02 07:34:10 UTC 2014 : Security manager installed using the Basic server security policy. Sun Feb 02 07:34:11 UTC 2014 : access denied ("java.net.SocketPermission" "localhost:1527" "listen,resolve") Sun Feb 02 07:34:11 UTC 2014 : access denied ("java.net.SocketPermission" "localhost:1527" "listen,resolve") java.security.AccessControlException: access denied ("java.net.SocketPermission" "localhost:1527" "listen,resolve") at java.security.AccessControlContext.checkPermission(AccessControlContext.java:372) at java.security.AccessController.checkPermission(AccessController.java:559) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at java.lang.SecurityManager.checkListen(SecurityManager.java:1134) at java.net.ServerSocket.bind(ServerSocket.java:375) at java.net.ServerSocket.<init>(ServerSocket.java:237) at javax.net.DefaultServerSocketFactory.createServerSocket(ServerSocketFactory.java:231) at org.apache.derby.impl.drda.NetworkServerControlImpl.createServerSocket(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.access$000(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at org.apache.derby.impl.drda.NetworkServerControlImpl.blockingStart(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.executeWork(Unknown Source) at org.apache.derby.drda.NetworkServerControl.main(Unknown Source) 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:606) at com.sun.enterprise.admin.cli.optional.DerbyControl.invokeNetworkServerControl(DerbyControl.java:158) at com.sun.enterprise.admin.cli.optional.DerbyControl.main(DerbyControl.java:245) java.security.AccessControlException: access denied ("java.net.SocketPermission" "localhost:1527" "listen,resolve") at java.security.AccessControlContext.checkPermission(AccessControlContext.java:372) at java.security.AccessController.checkPermission(AccessController.java:559) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at java.lang.SecurityManager.checkListen(SecurityManager.java:1134) at java.net.ServerSocket.bind(ServerSocket.java:375) at java.net.ServerSocket.<init>(ServerSocket.java:237) at javax.net.DefaultServerSocketFactory.createServerSocket(ServerSocketFactory.java:231) at org.apache.derby.impl.drda.NetworkServerControlImpl.createServerSocket(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.access$000(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at org.apache.derby.impl.drda.NetworkServerControlImpl.blockingStart(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.executeWork(Unknown Source) at org.apache.derby.drda.NetworkServerControl.main(Unknown Source) 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:606) at com.sun.enterprise.admin.cli.optional.DerbyControl.invokeNetworkServerControl(DerbyControl.java:158) at com.sun.enterprise.admin.cli.optional.DerbyControl.main(DerbyControl.java:245)
今後 JavaDB 側でも対応してくるとは思いますが「なんでもいいからとりあえず起動したい」という方のために私の行った対策を方法を書いておきます。
なお、以下の手順では以下のフォルダに GlassFish がインストールされていると想定しています。これはデフォルトのフォルダですが、もし変えている場合には逐次読み替えてください。
- C:\glassfish4
※ ちなみに、私の環境は Windows Azuer 上の Windows Server 2012 Datacenter ですがこちらはあまり影響していないと思います。
1. セキュリティポリシーファイルの作成
C:\glassfish4\javadb\bin\security.policy
grant { permission java.net.SocketPermission "localhost:1527", "listen"; permission java.security.AllPermission; };
2. JavaDB のJava起動オプションの追加
C:\glassfish4\javadb\bin\NetworkServerControl.bat (Linux の場合には NetworkServerControl)に以下のJava起動オプションを追記します。
セキュリティ・マネージャを有効にする
-Djava.security.manager |
Databaseが置いてあるフォルダのパスの指定
-Dderby.system.home=C:\glassfish4\glassfish\databases |
※ ここではデフォルトの Dabase の場所を指定しています。Dabaseファイルを別の場所に置かれている場合にはそちらを指定してください
ファイルの実際の行は以下のようになります。
NetworkServerControl.bat
... :runNoClasspath "%_JAVACMD%" %DERBY_OPTS% -Dderby.system.home=C:\glassfish4\glassfish\databases -Djava.security.manager -Djava.security.policy=security.policy -classpath "%LOCALCLASSPATH%" org.apache.derby.drda.NetworkServerControl %DERBY_ARGS% %DERBY_CMD_LINE_ARGS% goto end ...
4. JavaDB の起動
先ほど編集したNetworkServerControlでJavaDBを起動します
C:\glassfish4\javadb\bin>NetworkServerControl start Sun Feb 02 08:14:45 UTC 2014 : Apache Derby Network Server - 10.9.1.0 - (1344872) started and ready to accept connection s on port 1527
これで無事ポート1527 を Listen して起動できました!