Wildfly 8でEJBとJAX-WSを同じインタフェースで呼ぶ
JAX-RSのServiceを、同じ「Service」として例えばJSFのManagedBeanから、EJBでもJAX-WSでも呼べるようにしてみた。
それ自体は別に難しいことではなかったです。
Serviceクラス
// for JAX-RS @Path("todo") // for JAX-WS @WebService // for EJB @Stateless @LocalBean @Local(TodoServiceHome.ILocal.class) @Remote(TodoServiceHome.IRemote.class) // for CDI @Named public class TodoService implements TodoServiceHome { // for JAX-RS @PUT @Path("register") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) // for JAX-WS @WebMethod public Result register(TodoParam param) { ... } ... }
それ自体に@Pathを付けてJAX-RSにし、SLSBにして、WebServiceにする、というだけ。
でもEJBは@Statelessだけではなぜかダメで、@LocalBeanを付けないとダメだった。@LocalBeanを付けないといけないケースは、こんな感じ。ソースを追いかけるまではしてないので、何かお作法が足りなかったのかもしれないけれど。
- @Stateless単独 → @LocalBean不要
- @Stateless + @Path(JAX-RS) → @LocalBean不要
- @Stateless + @WebService → @LocalBean必要
ServiceHomeインタフェース
一応リモートからも呼べるようにということで、インタフェースを用意してあります。
@WebService public interface TodoServiceHome { @WebMethod Result register(TodoParam param); @WebMethod List<Todo> findAll(); @WebMethod Result remove(String id); @Local public interface ILocal extends TodoServiceHome { } @Remote public interface IRemote extends TodoServiceHome { } }
内部でインタフェース定義してるのはローカルとリモートの2つを使うときでもimplementsに書くのを1つで済ますためのものです。