じゃんけんなど、ユーザーがコードをアップロードできるゲームを開発する必要があります。それらはインターフェースクラスからいくつかのメソッドを実装する必要があり、私たちはそれらをゲームクラスで呼び出します。特別なことは何もありません。
ユーザーのコードはパッケージに含まれており、名前の衝突はありません
が、メイントピック:ユーザーAがユーザーBのクラスのメソッドを呼び出さないようにするにはどうすればよいですか?
これを行う1つの方法は、2つのクラスを異なるクラスローダーにロードすることです。完全に安全にするには、クラスローダーの障壁を回避する可能性のあるリフレクションやその他のメカニズムを停止するセキュリティサンドボックスでクラスを実行する必要もあります。
実はこれに欠陥があるのではないかと思います。2つの「プレーヤー」クラスが同じインターフェースを実装している場合、それらは共有インターフェースで定義されたメソッドを多形的に呼び出すことができます。それらが異なるクラスローダーにロードされ、したがってお互いのタイプを使用できないという事実はそれを止めません。
したがって、1つのクラス/オブジェクトが他のインスタンスをフェレットアウトするのを防ぐために、基本的にリフレクションのブロック(および適切なプログラミング)に依存しています。リフレクションをブロックすると、一方のクラスが他方のカプセル化を破ったり、共通のスーパークラスまたは共有インターフェイスで定義されていないメソッドを呼び出したりすることも防止されます。
プログラムに他のコードを含めて実行しても、メソッドの呼び出しを妨げるものは何もありません。
メソッドパッケージをプライベートにしたり、パッケージを封印したりすることもできますが、それでもリフレクションなどに対処する必要があります。
もし私があなたのところにいるなら、私は明確に定義されたネットワークプロトコルまたは標準の入力/出力を介してユーザーコードとインターフェースすることを検討します。
簡単な方法の1つは、パッケージの外部の誰もがそれらにアクセスできないように、すべてのメソッドに修飾子protected
またはdefault
アクセス修飾子があることを確認することです。
これらはすべて推測ですが、次の点に注意してください。
または、Rhinoで実行できるECMAScriptなど、実際のJavaコードの代わりにスクリプトをユーザーにアップロードさせることもできます。
それらがパブリックメソッドである限り、異なるクラスローダーに分離しない限り、それはできません。その場合、各クラスはお互いを見ることができません。
さまざまなクラスローダーでのロードは、Tomcat、JettyなどのWebコンテナーがさまざまなWebアプリケーションを分離する方法です。
別のアプローチは、カスタムセキュリティ実装をセットアップすることですが、クラスローダーソリューションよりも正しく設定するのははるかに困難です。