LoginSignup
0
0

S2JDBC-GenのGen-Entityでエラー

Last updated at Posted at 2023-03-10

概要

このページでまとめているエラーは、eclipseでSAStrutsを使ったウェブアプリケーションを作りたくて作業していた時に起きました。
ウェブアプリが動いて、次は宅内サーバーのDB(MariaDB)へアクセスできるようにしたいと思い、S2JDBCの利用を考えました。
S2JDBCのためには、まずS2JDBC-Genでエンティティを自動生成してもらうことが必要なようです。
プロジェクトはDoltengから作ったものなのでプロジェクトエクスプローラー等の、プロジェクト直下にs2jdbc-gen-build.xmlが作成されています。これを右クリックして、「実行」→「Ant ビルド...」を選び、gen-entityのみを選択して実行すれば手順としては問題ないはずですが、そこでエラーが起きました。

参考:S2JDBC-Genのセットアップ

環境

  • OS:macOS Ventura 13.2.1(ハードはiMac 21.5-inch 2019だったり、MacBook Pro 13-inch, 2020)
  • eclipse:2022-12 (4.26.0)

以下フレームワーク関連のバージョン

  • struts:1.2.9
  • sa-struts:1.0.4
  • s2-tiger:2.4.46
  • s2-framework:2.4.46
  • s2-extension:2.4.46
  • s2jdbc-gen:2.4.46
  • freemarker:2.3.13

最初のつまずき

s2jdbc-gen-build.xmlをAntでビルドした結果のコンソールが以下。

Buildfile: /Volumes/Seagate_mac/ファイル/workspace/eclipse/wasabiapp/s2jdbc-gen-build.xml
gen-entity:
[gen-entity] Java Result: 1

BUILD FAILED
/Volumes/Seagate_mac/ファイル/workspace/eclipse/wasabiapp/s2jdbc-gen-build.xml:40: エラー: メイン・クラスを検出およびロードできませんでした
原因: java.lang.ClassNotFoundException: 

対応

「S2JDBC-Gen メイン・クラスが見つからなかったかロードできません」等で調べると、以下が近そうですね。

こちらのページでは、特殊な環境向けの設定が悪さをしているとのこと。正直なところよくわかりませんが、私はmacOSなので全部UTF-8なのでは?と思い、特殊な環境向けの設定は必要ないと勝手に判断しました。
なので上記ページ通り、<jvmarg value="${vmarg.encoding}"/>を削除することでこちらのエラーは出なくなりました。
しかし、何も書かないのもなんか不安なので、少し触っていたところ、<jvmarg value="-Dfile.encoding=UTF-8"/>としてもエラーが出なくなったので、こちらの状態にしてあります。

<condition property="vmarg.encoding" value="-Dfile.encoding=UTF-8" else="">
  <isset property="eclipse.pdebuild.home"/>
</condition>

この部分がいらなくなっちゃうので、何も書かないでもよいかなと思います。そもそもこれがなぜ上手くいかないのかはわかれば追記します。

結果

以下の対応で当該のエラーは出なくなりました。

classpathref="classpath">
-   <jvmarg value="${vmarg.encoding}"/>
+   <jvmarg value="-Dfile.encoding=UTF-8"/>
</gen-entity>

2度目のつまずき

その後、s2jdbc-gen-build.xmlをAntでビルドした結果のコンソールが以下(長いのでエラーより前は途中から記載)。

...
[gen-entity] DEBUG 2023-03-09 21:11:23,177 [main] S2Containerを作成します。path=creator.dicon
[gen-entity] DEBUG 2023-03-09 21:11:23,193 [main] S2Containerを作成しました。path=creator.dicon
[gen-entity] DEBUG 2023-03-09 21:11:23,198 [main] S2Containerを作成しました。path=warmdeploy.dicon
[gen-entity] Java Result: 1

BUILD FAILED
/Users/wasabi/Documents/workspace/eclipse/wasabiapp/s2jdbc-gen-build.xml:40: Exception in thread "main" java.lang.ExceptionInInitializerError
	at org.seasar.framework.util.ResourcesUtil.getResourcesTypes(ResourcesUtil.java:163)
	at org.seasar.framework.convention.impl.NamingConventionImpl.addExistChecker(NamingConventionImpl.java:895)
	at org.seasar.framework.convention.impl.NamingConventionImpl.addRootPackageName(NamingConventionImpl.java:428)
	at org.seasar.framework.convention.impl.NamingConventionImpl.addRootPackageName(NamingConventionImpl.java:410)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.seasar.framework.util.MethodUtil.invoke(MethodUtil.java:96)
	at org.seasar.framework.beans.impl.BeanDescImpl.invoke(BeanDescImpl.java:218)
	at org.seasar.framework.container.assembler.AbstractMethodAssembler.invoke(AbstractMethodAssembler.java:132)
	at org.seasar.framework.container.assembler.AbstractMethodAssembler.invoke(AbstractMethodAssembler.java:96)
	at org.seasar.framework.container.assembler.DefaultInitMethodAssembler.assemble(DefaultInitMethodAssembler.java:49)
	at org.seasar.framework.container.deployer.SingletonComponentDeployer.assemble(SingletonComponentDeployer.java:69)
	at org.seasar.framework.container.deployer.SingletonComponentDeployer.deploy(SingletonComponentDeployer.java:48)
	at org.seasar.framework.container.deployer.SingletonComponentDeployer.init(SingletonComponentDeployer.java:76)
	at org.seasar.framework.container.impl.ComponentDefImpl.init(ComponentDefImpl.java:236)
	at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:563)
	at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:560)
	at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:560)
	at org.seasar.framework.container.factory.S2ContainerFactory.configure(S2ContainerFactory.java:234)
	at org.seasar.framework.container.factory.S2ContainerFactory.configure(S2ContainerFactory.java:211)
	at org.seasar.framework.container.factory.S2ContainerFactory.<clinit>(S2ContainerFactory.java:116)
	at org.seasar.framework.container.factory.SingletonS2ContainerFactory.init(SingletonS2ContainerFactory.java:152)
	at org.seasar.extension.jdbc.gen.internal.util.SingletonS2ContainerFactorySupport.init(SingletonS2ContainerFactorySupport.java:61)
	at org.seasar.extension.jdbc.gen.internal.command.AbstractCommand.init(AbstractCommand.java:201)
	at org.seasar.extension.jdbc.gen.internal.command.AbstractCommand.execute(AbstractCommand.java:160)
	at org.seasar.extension.jdbc.gen.internal.command.CommandInvokerImpl.invoke(CommandInvokerImpl.java:29)
	at org.seasar.extension.jdbc.gen.command.CommandAdapter.main(CommandAdapter.java:61)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.findLoadedClass(java.lang.String) accessible: module java.base does not "opens java.lang" to unnamed module @29428716
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
	at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
	at org.seasar.framework.util.ClassLoaderUtil.getFindLoadedClassMethod(ClassLoaderUtil.java:50)
	at org.seasar.framework.util.ClassLoaderUtil.<clinit>(ClassLoaderUtil.java:35)
	... 29 more

Total time: 1 second

対応

出ているエラー(「java.lang.ExceptionInInitializerError」「java.lang.reflect.InaccessibleObjectException」「module java.base does not "opens java.lang" to unnamed module」)等で調べると以下のページがかなり近そうです。

引数に--add-opens java.base/jdk.internal.loader=ALL-UNNAMEDをつけるとのこと。
さて、今回はAntでの実行ですし、javaコマンドじゃないのでどうアプローチしようかと考えました。「Ant ビルド...」を選んで、メインタブから引数を指定しても変わらず。
こちらのページにあるように、eclipse.iniに指定しても変わらず(そもそも初めから--add-opens java.base/java.lang=ALL-UNNAMEDの行がありますしね...)。
そういえば、さっきのつまずき中に、「jvmargはjvmに引数を渡している」とのような記述を見かけた気がします。

<jvmarg value="--add-opens=java.base/java.lang=ALL-UNNAMED" />

こちらを先ほどと同じところに追加してみました。すると無事、当該のエラーは出なくなりました。

結果

以下の対応で当該のエラーは出なくなりました。

classpathref="classpath">
   <jvmarg value="-Dfile.encoding=UTF-8"/>
+  <jvmarg value="--add-opens=java.base/java.lang=ALL-UNNAMED" />
</gen-entity>

3度目のつまずき

その後、s2jdbc-gen-build.xmlをAntでビルドした結果のコンソールが以下。
そろそろ、私の環境が悪いだけで、入れ直したりすればいけるんじゃないかと疑います。とはいえ、好転してそうな気がするので、頑張りましょう。

...
[gen-entity] DEBUG 2023-03-10 11:02:10,690 [main] S2Containerを作成しました。path=warmdeploy.dicon
[gen-entity] DEBUG 2023-03-10 11:02:10,703 [main] S2Containerを作成します。path=s2jdbc.dicon
[gen-entity] DEBUG 2023-03-10 11:02:10,705 [main] S2Containerを作成します。path=jdbc.dicon
[gen-entity] DEBUG 2023-03-10 11:02:10,707 [main] S2Containerを作成します。path=jta.dicon
[gen-entity] DEBUG 2023-03-10 11:02:10,717 [main] S2Containerを作成しました。path=jta.dicon
[gen-entity] DEBUG 2023-03-10 11:02:10,727 [main] S2Containerを作成しました。path=jdbc.dicon
[gen-entity] DEBUG 2023-03-10 11:02:10,727 [main] S2Containerを作成します。path=s2jdbc-internal.dicon
[gen-entity] DEBUG 2023-03-10 11:02:10,729 [main] S2Containerを作成します。path=convention.dicon
[gen-entity] DEBUG 2023-03-10 11:02:10,731 [main] S2Containerを作成しました。path=convention.dicon
[gen-entity] DEBUG 2023-03-10 11:02:10,734 [main] S2Containerを作成しました。path=s2jdbc-internal.dicon
[gen-entity] DEBUG 2023-03-10 11:02:10,751 [main] S2Containerを作成しました。path=s2jdbc.dicon
[gen-entity] Java Result: 1

BUILD FAILED
/Volumes/Seagate_mac/ファイル/workspace/eclipse/wasabiapp/s2jdbc-gen-build.xml:40: Exception in thread "main" org.seasar.framework.beans.IllegalPropertyRuntimeException: [ESSR0059]クラス(org.seasar.extension.dbcp.impl.XADataSourceImpl)のプロパティ(driverClassName)の設定に失敗しました。理由はorg.seasar.framework.exception.SIllegalArgumentException: [ESSR0098]クラス(org.seasar.extension.dbcp.impl.XADataSourceImpl)[jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27]の型(java.lang.String)[null]のプロパティ(driverClassName)に、型(java.lang.String)[null]の値(com.mysql.jdbc.Driver)を設定できませんでした。対象のクラスは(org.seasar.extension.dbcp.impl.XADataSourceImpl)[jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27]です。
	at org.seasar.framework.beans.impl.PropertyDescImpl.setValue(PropertyDescImpl.java:279)
	at org.seasar.framework.container.assembler.AbstractBindingTypeDef.setValue(AbstractBindingTypeDef.java:321)
	at org.seasar.framework.container.assembler.AbstractBindingTypeDef.bindManual(AbstractBindingTypeDef.java:127)
	at org.seasar.framework.container.assembler.AbstractBindingTypeDef.bind(AbstractBindingTypeDef.java:74)
	at org.seasar.framework.container.assembler.AccessTypePropertyDef.bind(AccessTypePropertyDef.java:50)
	at org.seasar.framework.container.assembler.AccessTypePropertyDef.bind(AccessTypePropertyDef.java:41)
	at org.seasar.framework.container.assembler.AutoPropertyAssembler.assemble(AutoPropertyAssembler.java:56)
	at org.seasar.framework.container.deployer.SingletonComponentDeployer.assemble(SingletonComponentDeployer.java:68)
	at org.seasar.framework.container.deployer.SingletonComponentDeployer.deploy(SingletonComponentDeployer.java:48)
	at org.seasar.framework.container.deployer.SingletonComponentDeployer.init(SingletonComponentDeployer.java:76)
	at org.seasar.framework.container.impl.ComponentDefImpl.init(ComponentDefImpl.java:236)
	at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:563)
	at org.seasar.framework.container.impl.ThreadSafeS2ContainerImpl.init(ThreadSafeS2ContainerImpl.java:172)
	at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:560)
	at org.seasar.framework.container.impl.ThreadSafeS2ContainerImpl.init(ThreadSafeS2ContainerImpl.java:172)
	at org.seasar.framework.container.factory.SingletonS2ContainerFactory.init(SingletonS2ContainerFactory.java:167)
	at org.seasar.extension.jdbc.gen.internal.util.SingletonS2ContainerFactorySupport.init(SingletonS2ContainerFactorySupport.java:61)
	at org.seasar.extension.jdbc.gen.internal.command.AbstractCommand.init(AbstractCommand.java:201)
	at org.seasar.extension.jdbc.gen.internal.command.AbstractCommand.execute(AbstractCommand.java:160)
	at org.seasar.extension.jdbc.gen.internal.command.CommandInvokerImpl.invoke(CommandInvokerImpl.java:29)
	at org.seasar.extension.jdbc.gen.command.CommandAdapter.main(CommandAdapter.java:61)
Caused by: org.seasar.framework.exception.SIllegalArgumentException: [ESSR0098]クラス(org.seasar.extension.dbcp.impl.XADataSourceImpl)[jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27]の型(java.lang.String)[null]のプロパティ(driverClassName)に、型(java.lang.String)[null]の値(com.mysql.jdbc.Driver)を設定できませんでした。対象のクラスは(org.seasar.extension.dbcp.impl.XADataSourceImpl)[jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27]です。
	at org.seasar.framework.beans.impl.PropertyDescImpl.setValue(PropertyDescImpl.java:258)
	... 20 more
Caused by: org.seasar.framework.exception.ClassNotFoundRuntimeException: [ESSR0044]クラスが見つかりませんでした。詳細はjava.lang.ClassNotFoundException: com.mysql.jdbc.Driver
	at org.seasar.framework.util.ClassUtil.forName(ClassUtil.java:100)
	at org.seasar.framework.util.DriverManagerUtil.registerDriver(DriverManagerUtil.java:41)
	at org.seasar.extension.dbcp.impl.XADataSourceImpl.setDriverClassName(XADataSourceImpl.java:77)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.seasar.framework.util.MethodUtil.invoke(MethodUtil.java:96)
	at org.seasar.framework.beans.impl.PropertyDescImpl.setValue(PropertyDescImpl.java:251)
	... 20 more
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:467)
	at org.seasar.framework.util.ClassUtil.forName(ClassUtil.java:98)
	... 28 more

Total time: 938 milliseconds

長いのでエラーより前は途中から記載ですが、エラーの前を少し多めに記載しました。
というのも、2度目のつまずきでは[gen-entity] DEBUG 2023-03-10 11:02:10,690 [main] S2Containerを作成しました。path=warmdeploy.diconの直後にエラーが出てましたが、今回はそのさらに後です。先ほども言いましたが、状況は好転している気がします。

対応

すいません、[jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27]の型(java.lang.String)[null]のプロパティ(driverClassName)に、型(java.lang.String)[null]の値(com.mysql.jdbc.Driver)を設定できませんでした。と書いてありますね。
jdbc.diconのdriverClassNameを変更していませんでした。URLやらuserやらは修正していたんですけどね。

結果

環境依存になりますので、記載はしません。jdbc.diconを環境に合わせて修正忘れずに、ということです。

4度目のつまずき(1, 2度目のつまずきと同様)

<jvmarg value="${vmarg.encoding}"/>を使っている他の行も、1, 2度目のつまずき同様に、以下のように修正していきます。

-  <jvmarg value="${vmarg.encoding}"/>
+  <jvmarg value="-Dfile.encoding=UTF-8"/>
+  <jvmarg value="--add-opens=java.base/java.lang=ALL-UNNAMED" />

最後に

戦いの末、ようやくS2JDBC-Genが動き、エンティティを作成してもらえました!!!
そもそも、Java1.7以下であれば起きないエラーも多いので、かなり環境依存ですが、1.8以上で同様のエラーが起きた方向けに書いてます。
現状の記載内容に関してもし詳細がわかれば随時、しっかりとした原因や正しい対策など追記したいと思います。
何か、間違っているところ、詳細、原因などコメントありましたら、よろしくお願いいたします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0