http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-alternative-and-stereotypes.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-alternative-and-stereotypes.adoc b/src/main/jbake/content/examples/cdi-alternative-and-stereotypes.adoc new file mode 100755 index 0000000..2f5e99d --- /dev/null +++ b/src/main/jbake/content/examples/cdi-alternative-and-stereotypes.adoc @@ -0,0 +1,138 @@ += cdi-alternative-and-stereotypes +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-alternative-and-stereotypes can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-alternative-and-stereotypes + += Introduction + +CDI is a revolution for Java EE world. This specification is the best one to avoid coupling between classes. + +This example simply aims to override bindings at runtime to simplify mocking work. + +It uses two kind of mocks: +1) a mock with no implementation in the classloader +2) a mock with an implementation in the classloader + +The mock answer from CDI is called *alternative*. + +Annotating `@Alternative` a class will mean it will replace any implementation if there is no other implementation +or if it is forced (through `META-INF/beans.xml`). + += Code explanation +== main code + +We use an EJB `Jouney` to modelize a journey where the vehicle and the society can change. Here an EJB is used simply +because it simplifies the test. A jouney wraps the vehicle and society information. + +We define then two interfaces to inject it in the `Journey` EJB: `Vehicle` and `Society`. + +Finally we add an implementation for `Scociety` interface: `LowCostCompanie`. + +If we don't go further `Journey` object will not be able to be created because no `Vehicle` implementation is available. + +Note: if we suppose we have a `Vehicle` implementation, the injected Society should be `LowCostCompanie`. + +== test code + +The goal here is to test our `Journey` EJB. So we have to provide a `Vehicle` implementation: `SuperCar`. + +We want to force the `Society` implementation (for any reason) by our test implementation: `AirOpenEJB`. + +One solution could simply be to add `@Alternative` annotation on `AirOpenEJB` and activate it through +the `META-INF/beans.xml` file. + +Here we want to write more explicit code. So we want to replace the `@Alternative` annotation by `@Mock` one. + +So we simply define an `@Mock` annotation for classes, resolvable at runtime which is a stereotype (`@Stereotype`) +which replace `@Alternative`. + +Here is the annotation: + + +[source,java] +---- +@Stereotype // we define a stereotype +@Retention(RUNTIME) // resolvable at runtime +@Target(TYPE) // this annotation is a class level one +@Alternative // it replace @Alternative +public @interface Mock {} + +Note: you can add more CDI annotations after `@Alternative` and it will get the behavior expected (the scope for instance). + +So now we have our `@Mock` annotation which is a stereotype able to replace `@Alternative` annotation +we simply add this annotation to our mocks. + +If you run it now you'll have this exception: + +javax.enterprise.inject.UnsatisfiedResolutionException: Api type [org.superbiz.cdi.stereotype.Vehicle] is not found with the qualifiers +Qualifiers: [@javax.enterprise.inject.Default()] +for injection into Field Injection Point, field name : vehicle, Bean Owner : [Journey, Name:null, WebBeans Type:ENTERPRISE, API Types:[java.lang.Object,org.superbiz.cdi.stereotype.Journey], Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]] + +It means the stereotype is not activated. To do it simply add it to your `META-INF/beans.xml`: + +<alternatives> + <stereotype>org.superbiz.cdi.stereotype.Mock</stereotype> +</alternatives> + +Note: if you don't specify `AirOpenEJB` as `@Alternative` (done through our mock annotation) you'll get this exception: + +Caused by: javax.enterprise.inject.AmbiguousResolutionException: There is more than one api type with : org.superbiz.cdi.stereotype.Society with qualifiers : Qualifiers: [@javax.enterprise.inject.Default()] +for injection into Field Injection Point, field name : society, Bean Owner : [Journey, Name:null, WebBeans Type:ENTERPRISE, API Types:[org.superbiz.cdi.stereotype.Journey,java.lang.Object], Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]] +found beans: +AirOpenEJB, Name:null, WebBeans Type:MANAGED, API Types:[org.superbiz.cdi.stereotype.Society,org.superbiz.cdi.stereotype.AirOpenEJB,java.lang.Object], Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default] +LowCostCompanie, Name:null, WebBeans Type:MANAGED, API Types:[org.superbiz.cdi.stereotype.Society,org.superbiz.cdi.stereotype.LowCostCompanie,java.lang.Object], Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default] + +which simply means two implementations are available for the same injection point (`Journey.society`). + +# Conclusion + +With CDI it is really easy to define annotations with a strong meaning. You can define business annotations +or simply technical annotations to simplify your code (as we did with the mock annotation). + +Note: if for instance you used qualifiers to inject societies you could have put all these qualifiers on +the mock class or defined a `@SocietyMock` annotation to be able to inject the same implementation for +all qualifiers in your tests. + +# Output + +Running org.superbiz.cdi.stereotype.StereotypeTest +Apache OpenEJB 7.0.0-SNAPSHOT build: 20111030-07:54 +http://tomee.apache.org/ +INFO - openejb.home = /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes +INFO - openejb.base = /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes +INFO - Using 'javax.ejb.embeddable.EJBContainer=true' +INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Found EjbModule in classpath: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes/target/test-classes +INFO - Found EjbModule in classpath: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes/target/classes +INFO - Beginning load: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes/target/test-classes +INFO - Beginning load: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes/target/classes +INFO - Configuring enterprise application: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes +INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +INFO - Auto-creating a container for bean cdi-alternative-and-stereotypes_test.Comp: Container(type=MANAGED, id=Default Managed Container) +INFO - Configuring Service(id=Default Singleton Container, type=Container, provider-id=Default Singleton Container) +INFO - Auto-creating a container for bean Journey: Container(type=SINGLETON, id=Default Singleton Container) +INFO - Enterprise application "/opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes" loaded. +INFO - Assembling app: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes +INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/cdi-alternative-and-stereotypes_test.Comp!org.apache.openejb.BeanContext$Comp") +INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/cdi-alternative-and-stereotypes_test.Comp") +INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/cdi-alternative-and-stereotypes.Comp!org.apache.openejb.BeanContext$Comp") +INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/cdi-alternative-and-stereotypes.Comp") +INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/Journey!org.superbiz.cdi.stereotype.Journey") +INFO - Jndi(name="java:global/cdi-alternative-and-stereotypes/Journey") +INFO - Jndi(name="java:global/EjbModule162291475/org.superbiz.cdi.stereotype.StereotypeTest!org.superbiz.cdi.stereotype.StereotypeTest") +INFO - Jndi(name="java:global/EjbModule162291475/org.superbiz.cdi.stereotype.StereotypeTest") +INFO - Created Ejb(deployment-id=cdi-alternative-and-stereotypes_test.Comp, ejb-name=cdi-alternative-and-stereotypes_test.Comp, container=Default Managed Container) +INFO - Created Ejb(deployment-id=cdi-alternative-and-stereotypes.Comp, ejb-name=cdi-alternative-and-stereotypes.Comp, container=Default Managed Container) +INFO - Created Ejb(deployment-id=org.superbiz.cdi.stereotype.StereotypeTest, ejb-name=org.superbiz.cdi.stereotype.StereotypeTest, container=Default Managed Container) +INFO - Created Ejb(deployment-id=Journey, ejb-name=Journey, container=Default Singleton Container) +INFO - Started Ejb(deployment-id=cdi-alternative-and-stereotypes_test.Comp, ejb-name=cdi-alternative-and-stereotypes_test.Comp, container=Default Managed Container) +INFO - Started Ejb(deployment-id=cdi-alternative-and-stereotypes.Comp, ejb-name=cdi-alternative-and-stereotypes.Comp, container=Default Managed Container) +INFO - Started Ejb(deployment-id=org.superbiz.cdi.stereotype.StereotypeTest, ejb-name=org.superbiz.cdi.stereotype.StereotypeTest, container=Default Managed Container) +INFO - Started Ejb(deployment-id=Journey, ejb-name=Journey, container=Default Singleton Container) +INFO - Deployed Application(path=/opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes) +INFO - Undeploying app: /opt/dev/openejb/openejb-trunk/examples/cdi-alternative-and-stereotypes +
http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-application-scope.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-application-scope.adoc b/src/main/jbake/content/examples/cdi-application-scope.adoc new file mode 100755 index 0000000..cf1730f --- /dev/null +++ b/src/main/jbake/content/examples/cdi-application-scope.adoc @@ -0,0 +1,160 @@ += CDI @ApplicationScoped +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-application-scope can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-application-scope + + +This example show the use of `@ApplicationScoped` annotation for injected objects. An object +which is defined as `@ApplicationScoped` is created once for the duration of the application. + += Example + +This example depicts a similar scenario to cdi-request-scope. A restaurant guest orders +a soup from the waiter. The waiter then delivers the soup back to the guest. Another +guest can order the same soup that was ordered by the previous client - this is where +the application scope is used. + +== Waiter + +The `Waiter` session bean receives a request from the test class via the `orderSoup()` method +and sets the name for the `soup` field. The `orderWhatTheOtherGuyHad()` method returns +the name of the `soup` field. + + +[source,java] +---- +@Stateless +public class Waiter { + + @Inject + public Soup soup; + + public String orderSoup(String name){ + soup.setName(name); + return soup.getName(); + } + + public String orderWhatTheOtherGuyHad() { + String name = soup.getName(); + return name; + } +} +---- + + +== Soup + +The `Soup` class is an injectable POJO, defined as `@ApplicationScoped`. This means that an instance +will be created only once for the duration of the whole application. Try changing the `@ApplicationScoped` +annotation to `@RequestScoped` and see what happens. + + +[source,java] +---- +@ApplicationScoped +public class Soup { + + private String name = "Soup of the day"; + + @PostConstruct + public void afterCreate() { + System.out.println("Soup created"); + } + + public String getName() { + return name; + } + + public void setName(String name){ + this.name = name; + } +} +---- + + + += Test Case + +This is the entry class for this example. First a soup is ordered via `orderSoup()` method. +This initiates the `soup` field. Next, `orderWhatTheOtherGuyHad()` method returns the soup +from the application context. + + +[source,java] +---- +public class RestaurantTest { + + private static String TOMATO_SOUP = "Tomato Soup"; + private EJBContainer container; + + @EJB + private Waiter joe; + + @Before + public void startContainer() throws Exception { + container = EJBContainer.createEJBContainer(); + container.getContext().bind("inject", this); + } + + @Test + public void orderSoup(){ + String someSoup = joe.orderSoup(TOMATO_SOUP); + assertEquals(TOMATO_SOUP, someSoup); + + String sameSoup = joe.orderWhatTheOtherGuyHad(); + assertEquals(TOMATO_SOUP, sameSoup); + } + + @After + public void closeContainer() throws Exception { + container.close(); + } +} +---- + + += Running + +In the output you can see that there is just one `Soup` instance created - one for +the whole application. + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.cdi.applicationscope.RestaurantTest +Apache OpenEJB 7.0.0-SNAPSHOT build: 20111224-11:09 +http://tomee.apache.org/ +INFO - openejb.home = C:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope +INFO - openejb.base = C:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope +INFO - Using 'javax.ejb.embeddable.EJBContainer=true' +INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Found EjbModule in classpath: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope\target\classes +INFO - Beginning load: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope\target\classes +INFO - Configuring enterprise application: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope +INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +INFO - Auto-creating a container for bean cdi-application-scope.Comp: Container(type=MANAGED, id=Default Managed Container) +INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) +INFO - Auto-creating a container for bean Waiter: Container(type=STATELESS, id=Default Stateless Container) +INFO - Enterprise application "c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope" loaded. +INFO - Assembling app: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope +INFO - Jndi(name="java:global/cdi-application-scope/Waiter!org.superbiz.cdi.applicationscope.Waiter") +INFO - Jndi(name="java:global/cdi-application-scope/Waiter") +INFO - Created Ejb(deployment-id=Waiter, ejb-name=Waiter, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=Waiter, ejb-name=Waiter, container=Default Stateless Container) +INFO - Deployed Application(path=c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope) +Soup created +INFO - Undeploying app: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.42 sec + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +---- + http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-basic.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-basic.adoc b/src/main/jbake/content/examples/cdi-basic.adoc new file mode 100755 index 0000000..8097c63 --- /dev/null +++ b/src/main/jbake/content/examples/cdi-basic.adoc @@ -0,0 +1,191 @@ += CDI @Inject +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-basic can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-basic + + +To use `@Inject`, the first thing you need is a `META-INF/beans.xml` file in the module +or jar. This effectively turns on CDI and allows the `@Inject` references to work. +No `META-INF/beans.xml` no injection, period. This may seem overly strict, +but it is not without reason. The CDI API is a bit greedy and does consume a fair +about of resources by design. + +When the container constructs a bean with an `@Inject` reference, +it will first find or create the object that will be injected. For the sake of +simplicity, the is example has a basic `Faculty` pojo with a no-arg constructor. Anyone +referencing `@Inject Faculty` will get their own instance of `Faculty`. If the desire +is to share the same instance of `Faculty`, see the concept of `scopes` -- this is +exactly what scopes are for. + += Example + +In this example we have an `@Stateless` bean `Course` with an `@Inject` reference to an +object of type `Faculty`. When `Course` is created, the container will also create an +instance of `Faculty`. The `@PostConstruct` will be called on the `Faculty`, +then the `Faculty` instance will be injected into the `Course` bean. Finally, the +`@PostConstruct` will be invoked on `Course` and then we're done. All instances will +have been created. + +The `CourseTest` test case drives this creation process by having `Course` injected +into it in its `@Setup` method. By the time our `@Test` method is invoked, +all the real work should be done and we should be ready to go. In the test case we do +some basic asserts to ensure everything was constructed, all `@PostConstruct` methods +called and everyting injected. + +== Faculty <small>a basic injectable pojo</small> + + +[source,java] +---- +public class Faculty { + + private List<String> facultyMembers; + + private String facultyName; + + @PostConstruct + public void initialize() { + this.facultyMembers = new ArrayList<String>(); + facultyMembers.add("Ian Schultz"); + facultyMembers.add("Diane Reyes"); + facultyName = "Computer Science"; + } + + public List<String> getFacultyMembers() { + return facultyMembers; + } + + public String getFacultyName() { + return facultyName; + } + +} +---- + + +== Course <small>a simple session bean</small> + + +[source,java] +---- +@Stateless +public class Course { + + @Inject + private Faculty faculty; + + private String courseName; + + private int capacity; + + @PostConstruct + private void init() { + assert faculty != null; + + // These strings can be externalized + // We'll see how to do that later + this.courseName = "CDI 101 - Introduction to CDI"; + this.capacity = 100; + } + + public String getCourseName() { + return courseName; + } + + public int getCapacity() { + return capacity; + } + + public Faculty getFaculty() { + return faculty; + } +} +---- + + += Test Case + + +[source,java] +---- +public class CourseTest extends TestCase { + + @EJB + private Course course; + + @Before + public void setUp() throws Exception { + EJBContainer.createEJBContainer().getContext().bind("inject", this); + } + + @Test + public void test() { + + // Was the EJB injected? + assertTrue(course != null); + + // Was the Course @PostConstruct called? + assertNotNull(course.getCourseName()); + assertTrue(course.getCapacity() > 0); + + // Was a Faculty instance injected into Course? + final Faculty faculty = course.getFaculty(); + assertTrue(faculty != null); + + // Was the @PostConstruct called on Faculty? + assertEquals(faculty.getFacultyName(), "Computer Science"); + assertEquals(faculty.getFacultyMembers().size(), 2); + } +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.cdi.basic.CourseTest +Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 +http://tomee.apache.org/ +INFO - openejb.home = /Users/dblevins/examples/cdi-basic +INFO - openejb.base = /Users/dblevins/examples/cdi-basic +INFO - Using 'javax.ejb.embeddable.EJBContainer=true' +INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Found EjbModule in classpath: /Users/dblevins/examples/cdi-basic/target/classes +INFO - Beginning load: /Users/dblevins/examples/cdi-basic/target/classes +INFO - Configuring enterprise application: /Users/dblevins/examples/cdi-basic +INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +INFO - Auto-creating a container for bean cdi-basic.Comp: Container(type=MANAGED, id=Default Managed Container) +INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) +INFO - Auto-creating a container for bean Course: Container(type=STATELESS, id=Default Stateless Container) +INFO - Enterprise application "/Users/dblevins/examples/cdi-basic" loaded. +INFO - Assembling app: /Users/dblevins/examples/cdi-basic +INFO - Jndi(name="java:global/cdi-basic/cdi-basic.Comp!org.apache.openejb.BeanContext$Comp") +INFO - Jndi(name="java:global/cdi-basic/cdi-basic.Comp") +INFO - Jndi(name="java:global/cdi-basic/Course!org.superbiz.cdi.basic.Course") +INFO - Jndi(name="java:global/cdi-basic/Course") +INFO - Jndi(name="java:global/EjbModule1833350875/org.superbiz.cdi.basic.CourseTest!org.superbiz.cdi.basic.CourseTest") +INFO - Jndi(name="java:global/EjbModule1833350875/org.superbiz.cdi.basic.CourseTest") +INFO - Created Ejb(deployment-id=Course, ejb-name=Course, container=Default Stateless Container) +INFO - Created Ejb(deployment-id=cdi-basic.Comp, ejb-name=cdi-basic.Comp, container=Default Managed Container) +INFO - Created Ejb(deployment-id=org.superbiz.cdi.basic.CourseTest, ejb-name=org.superbiz.cdi.basic.CourseTest, container=Default Managed Container) +INFO - Started Ejb(deployment-id=Course, ejb-name=Course, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=cdi-basic.Comp, ejb-name=cdi-basic.Comp, container=Default Managed Container) +INFO - Started Ejb(deployment-id=org.superbiz.cdi.basic.CourseTest, ejb-name=org.superbiz.cdi.basic.CourseTest, container=Default Managed Container) +INFO - Deployed Application(path=/Users/dblevins/examples/cdi-basic) +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.126 sec + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +---- + http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-ejbcontext-jaas.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-ejbcontext-jaas.adoc b/src/main/jbake/content/examples/cdi-ejbcontext-jaas.adoc new file mode 100755 index 0000000..b94d662 --- /dev/null +++ b/src/main/jbake/content/examples/cdi-ejbcontext-jaas.adoc @@ -0,0 +1,9 @@ += cdi-ejbcontext-jaas +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-ejbcontext-jaas can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-ejbcontext-jaas + +No README.md yet, be the first to contribute one! http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-events.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-events.adoc b/src/main/jbake/content/examples/cdi-events.adoc new file mode 100755 index 0000000..a7e43c4 --- /dev/null +++ b/src/main/jbake/content/examples/cdi-events.adoc @@ -0,0 +1,40 @@ += cdi-events +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-events can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-events + += CDI events: loose coupling and extensibility + +CDI allows you to extend business code by the Notifier/Observer pattern. + +To do it you simply inject a field `Event` in the notifier class. This class is a template +and the parameter type is the object type to fire. Then when you want to notify observers +you simply call the method fire of the event object passing as a parameter the event itself +(your own class!). + +On the other side you annotated a method parameter `@Observes` and the parameter type is the sent type +by the notifier. + +Note: of course you can add qualifiers to be more precise on your events. + += The example + +The example is pretty simple: an ejb uses the `@Schedule` annotation to get a notification each second. +The each second this EJB will send the current date through CDI events. + +This is our "business" code. It is a simple behavior (nothing). + +In our test (which is considered as an extension) we created an observer (`Observer` class) +which simply store and log each received date. + +The test itself (`EventTest`) simply verifies the dates were received. + += Conclusion + +CDI let's implement very easily plugins through this event mecanism. + +If you go further and look at CDI plugin API you'll realize it is simply the same kind +of events. CDI events is really the basis of CDI. http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-interceptors.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-interceptors.adoc b/src/main/jbake/content/examples/cdi-interceptors.adoc new file mode 100755 index 0000000..e973203 --- /dev/null +++ b/src/main/jbake/content/examples/cdi-interceptors.adoc @@ -0,0 +1,268 @@ += CDI Interceptors +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-interceptors can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-interceptors + + +Let's write a simple application that would allow us to book tickets for a movie show. As with all applications, logging is one cross-cutting concern that we have. Apart from that, there are some methods in our application, that can be accessed only in the working hours. If accessed at non-working-hours we'll throw out an AccessDeniedException. + +How do we mark which methods are to be intercepted? Wouldn't it be handy to annotate a method like + + +[source,java] +---- +@Log +public void aMethod(){...} + +or + +@TimeRestricted +public void bMethod(){...} + +Let's create these annotations that would "mark" a method for interception. + +@InterceptorBinding +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +public @interface Log { +} +---- + + +And + + +[source,java] +---- +@InterceptorBinding +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +public @interface TimeRestricted { +} +---- + + +Sure, you haven't missed the `@InterceptorBinding` annotation above! Now that our custom annotations are created, lets attach them (or to use a better term for it, "bind them") to interceptors. + +So here's our logging interceptor. An `@AroundInvoke` method and we are almost done. + + +[source,java] +---- +@Interceptor +@Log //binding the interceptor here. now any method annotated with @Log would be intercepted by logMethodEntry +public class BookForAShowLoggingInterceptor implements Serializable { + private static final long serialVersionUID = 8139854519874743530L; + private Logger logger = Logger.getLogger("BookForAShowApplicationLogger"); + @AroundInvoke + public Object logMethodEntry(InvocationContext ctx) throws Exception { + logger.info("Before entering method:" + ctx.getMethod().getName()); + InterceptionOrderTracker.getMethodsInterceptedList().add(ctx.getMethod().getName()); + InterceptionOrderTracker.getInterceptedByList().add(this.getClass().getSimpleName()); + return ctx.proceed(); + } +} +---- + + +Now the `@Log` annotation we created is bound to this interceptor. (Likewise we bind `@TimeRestrict` for `TimeBasedRestrictingInterceptor`. See links below for source) + +That done, let's annotate at class-level or method-level and have fun intercepting! + + +[source,java] +---- +@Log +@Stateful +public class BookForAShowOneInterceptorApplied implements Serializable { + private static final long serialVersionUID = 6350400892234496909L; + public List<String> getMoviesList() { + List<String> moviesAvailable = new ArrayList<String>(); + moviesAvailable.add("12 Angry Men"); + moviesAvailable.add("Kings speech"); + return moviesAvailable; + } + public Integer getDiscountedPrice(int ticketPrice) { + return ticketPrice - 50; + } + // assume more methods are present +} +---- + + +The `@Log` annotation applied at class level denotes that all the methods should be intercepted with `BookForAShowLoggingInterceptor`. + +Before we say "all done" there's one last thing we are left with! To enable the interceptors! + +Lets quickly put up a `beans.xml` file like the following in `src/main/resources/META-INF/beans.xml`: + + +[source,xml] +---- +<beans> + <interceptors> + <class>org.superbiz.cdi.bookshow.interceptors.BookForAShowLoggingInterceptor + </class> + <class>org.superbiz.cdi.bookshow.interceptors.TimeBasedRestrictingInterceptor + </class> + </interceptors> +</beans> +---- + + + +By default, a bean archive has no enabled interceptors bound via interceptor +bindings. An interceptor must be explicitly enabled by listing its class +in the `beans.xml`. + +Those lines in `beans.xml` not only "enable" the interceptors, but also define the "order of execution" of the interceptors. + +The order in with a method is annotated has no real significance. +Eg: + + +[source,java] +---- +@TimeRestrict +@Log +void cMethod(){} + +Here the `BookForAShowLoggingInterceptor` would be applied first and then `TimeBasedRestrictingInterceptor` + +So now you know that the order is only determined by the order of definition in `beans.xml`. Interceptors which occur earlier in the list are called first. + +Also note that a method can be marked for interception by multiple interceptors by applying multiple annotations as above. + +This brings us to another question. In the above case there were two interceptors applied together. What if I would require about 4 such interceptors that would go along.... Having to annotate so much makes the code a little clumsy? + +No worries! Just create a custom annotation which inherits from others + +@Inherited +@InterceptorBinding +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +@Log +@TimeRestricted +public @interface TimeRestrictAndLog { +} +---- + + +This is interceptor binding inheritance. + +The code below demonstrates the many cases that we have discussed. + +Not to forget, the old style binding with `@Interceptors(WhicheverInterceptor.class)` is also supported. Have a look at `BookForAShowOldStyleInterceptorBinding` where the comments explain how the newer way discussed above is better. + += The Code + +== BookForAShowOneInterceptorApplied + +`BookForAShowOneInterceptorApplied` shows a simple `@Log` interceptor applied. + + +[source,java] +---- +package org.superbiz.cdi.bookshow.beans; + +import org.superbiz.cdi.bookshow.interceptorbinding.Log; + +import javax.ejb.Stateful; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@Log +@Stateful +public class BookForAShowOneInterceptorApplied implements Serializable { + private static final long serialVersionUID = 6350400892234496909L; + + public List<String> getMoviesList() { + List<String> moviesAvailable = new ArrayList<String>(); + moviesAvailable.add("12 Angry Men"); + moviesAvailable.add("Kings speech"); + return moviesAvailable; + } + + public Integer getDiscountedPrice(int ticketPrice) { + return ticketPrice - 50; + } +} +---- + + +== BookForAShowTwoInterceptorsApplied + +`BookForAShowTwoInterceptorsApplied` shows both `@Log` and `@TimeRestricted` being applied. + + +[source,java] +---- +package org.superbiz.cdi.bookshow.beans; + +import org.superbiz.cdi.bookshow.interceptorbinding.Log; +import org.superbiz.cdi.bookshow.interceptorbinding.TimeRestricted; + +import javax.ejb.Stateful; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@Log +@Stateful +public class BookForAShowTwoInterceptorsApplied implements Serializable { + private static final long serialVersionUID = 6350400892234496909L; + + public List<String> getMoviesList() { + List<String> moviesAvailable = new ArrayList<String>(); + moviesAvailable.add("12 Angry Men"); + moviesAvailable.add("Kings speech"); + return moviesAvailable; + } + + @TimeRestricted + public Integer getDiscountedPrice(int ticketPrice) { + return ticketPrice - 50; + } +} +---- + + +== BookShowInterceptorBindingInheritanceExplored + +`BookShowInterceptorBindingInheritanceExplored` shows how `@TimeRestrictAndLog` (interceptor-binding-inheritance) can be used as an alternative for annotating a method with multiple annotations explicitly. + + +[source,java] +---- +package org.superbiz.cdi.bookshow.beans; + +import org.superbiz.cdi.bookshow.interceptorbinding.TimeRestrictAndLog; + +import javax.ejb.Stateful; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@Stateful +public class BookShowInterceptorBindingInheritanceExplored implements Serializable { + private static final long serialVersionUID = 6350400892234496909L; + + public List<String> getMoviesList() { + List<String> moviesAvailable = new ArrayList<String>(); + moviesAvailable.add("12 Angry Men"); + moviesAvailable.add("Kings speech"); + return moviesAvailable; + } + + @TimeRestrictAndLog + public Integer getDiscountedPrice(int ticketPrice) { + return ticketPrice - 50; + } +} +---- + + http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-produces-disposes.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-produces-disposes.adoc b/src/main/jbake/content/examples/cdi-produces-disposes.adoc new file mode 100755 index 0000000..30578e7 --- /dev/null +++ b/src/main/jbake/content/examples/cdi-produces-disposes.adoc @@ -0,0 +1,316 @@ += CDI Produces Disposes +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-produces-disposes can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-produces-disposes + + +*Help us document this example! Click the blue pencil icon in the upper right to edit this page.* + +== ConsoleHandler + + +[source,java] +---- +package org.superbiz.cdi.produces.disposes; + +public class ConsoleHandler implements LogHandler { + + private String name; + + public ConsoleHandler(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void writeLog(String s) { + System.out.printf("##### Handler: %s, Writing to the console!\n", getName()); + } +} +---- + + +== DatabaseHandler + + +[source,java] +---- +package org.superbiz.cdi.produces.disposes; + +public class DatabaseHandler implements LogHandler { + + private String name; + + public DatabaseHandler(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void writeLog(String s) { + System.out.printf("##### Handler: %s, Writing to the database!\n", getName()); + // Use connection to write log to database + } +} +---- + + +== FileHandler + + +[source,java] +---- +package org.superbiz.cdi.produces.disposes; + +public class FileHandler implements LogHandler { + + private String name; + + public FileHandler(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void writeLog(String s) { + System.out.printf("##### Handler: %s, Writing to the file!\n", getName()); + // Write to log file + } +} +---- + + +== LogFactory + + +[source,java] +---- +package org.superbiz.cdi.produces.disposes; + +import javax.enterprise.inject.Disposes; +import javax.enterprise.inject.Produces; + +public class LogFactory { + + private int type = 2; + + @Produces + public LogHandler getLogHandler() { + switch (type) { + case 1: + return new FileHandler("@Produces created FileHandler!"); + case 2: + return new DatabaseHandler("@Produces created DatabaseHandler!"); + case 3: + default: + return new ConsoleHandler("@Produces created ConsoleHandler!"); + } + } + + public void closeLogHandler(@Disposes LogHandler handler) { + switch (type) { + case 1: + System.out.println("Closing File handler!"); + break; + case 2: + System.out.println("Closing DB handler!"); + break; + case 3: + default: + System.out.println("Closing Console handler!"); + } + } +} +---- + + +== Logger + + +[source,java] +---- +package org.superbiz.cdi.produces.disposes; + +public interface Logger { + + public void log(String s); + + public LogHandler getHandler(); +} +---- + + +== LoggerImpl + + +[source,java] +---- +package org.superbiz.cdi.produces.disposes; + +import javax.inject.Inject; +import javax.inject.Named; + +@Named("logger") +public class LoggerImpl implements Logger { + + @Inject + private LogHandler handler; + + @Override + public void log(String s) { + getHandler().writeLog(s); + } + + public LogHandler getHandler() { + return handler; + } +} +---- + + +== LogHandler + + +[source,java] +---- +package org.superbiz.cdi.produces.disposes; + +public interface LogHandler { + + public String getName(); + + public void writeLog(String s); +} +---- + + +== beans.xml + + +[source,xml] +---- +<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee + http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> + +</beans> +---- + + +== LoggerTest + + +[source,java] +---- +package org.superbiz.cdi.produces.disposes; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.ejb.embeddable.EJBContainer; +import javax.inject.Inject; +import javax.naming.Context; + +import static junit.framework.Assert.assertNotNull; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class LoggerTest { + + @Inject + Logger logger; + + private Context ctxt; + + @Before + public void setUp() { + try { + ctxt = EJBContainer.createEJBContainer().getContext(); + ctxt.bind("inject", this); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @After + public void cleanUp() { + try { + ctxt.unbind("inject"); + ctxt.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testLogHandler() { + assertNotNull(logger); + assertFalse("Handler should not be a ConsoleHandler", logger.getHandler() instanceof ConsoleHandler); + assertFalse("Handler should not be a FileHandler", logger.getHandler() instanceof FileHandler); + assertTrue("Handler should be a DatabaseHandler", logger.getHandler() instanceof DatabaseHandler); + logger.log("##### Testing write\n"); + logger = null; + } + +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.cdi.produces.disposes.LoggerTest +Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 +http://tomee.apache.org/ +INFO - openejb.home = /Users/dblevins/examples/cdi-produces-disposes +INFO - openejb.base = /Users/dblevins/examples/cdi-produces-disposes +INFO - Using 'javax.ejb.embeddable.EJBContainer=true' +INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Found EjbModule in classpath: /Users/dblevins/examples/cdi-produces-disposes/target/classes +INFO - Beginning load: /Users/dblevins/examples/cdi-produces-disposes/target/classes +INFO - Configuring enterprise application: /Users/dblevins/examples/cdi-produces-disposes +INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +INFO - Auto-creating a container for bean cdi-produces-disposes.Comp: Container(type=MANAGED, id=Default Managed Container) +INFO - Enterprise application "/Users/dblevins/examples/cdi-produces-disposes" loaded. +INFO - Assembling app: /Users/dblevins/examples/cdi-produces-disposes +INFO - Jndi(name="java:global/cdi-produces-disposes/cdi-produces-disposes.Comp!org.apache.openejb.BeanContext$Comp") +INFO - Jndi(name="java:global/cdi-produces-disposes/cdi-produces-disposes.Comp") +INFO - Jndi(name="java:global/EjbModule10202458/org.superbiz.cdi.produces.disposes.LoggerTest!org.superbiz.cdi.produces.disposes.LoggerTest") +INFO - Jndi(name="java:global/EjbModule10202458/org.superbiz.cdi.produces.disposes.LoggerTest") +INFO - Created Ejb(deployment-id=cdi-produces-disposes.Comp, ejb-name=cdi-produces-disposes.Comp, container=Default Managed Container) +INFO - Created Ejb(deployment-id=org.superbiz.cdi.produces.disposes.LoggerTest, ejb-name=org.superbiz.cdi.produces.disposes.LoggerTest, container=Default Managed Container) +INFO - Started Ejb(deployment-id=cdi-produces-disposes.Comp, ejb-name=cdi-produces-disposes.Comp, container=Default Managed Container) +INFO - Started Ejb(deployment-id=org.superbiz.cdi.produces.disposes.LoggerTest, ejb-name=org.superbiz.cdi.produces.disposes.LoggerTest, container=Default Managed Container) +INFO - Deployed Application(path=/Users/dblevins/examples/cdi-produces-disposes) +##### Handler: @Produces created DatabaseHandler!, Writing to the database! +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.02 sec + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +---- + + http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-produces-field.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-produces-field.adoc b/src/main/jbake/content/examples/cdi-produces-field.adoc new file mode 100755 index 0000000..9a220d9 --- /dev/null +++ b/src/main/jbake/content/examples/cdi-produces-field.adoc @@ -0,0 +1,321 @@ += CDI field producer +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-produces-field can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-produces-field + + +This example shows the usage of the @Produces annotation. @Produces is a CDI mechanism which allows defining a source + for injection. This example shows one of two ways of declaring a producer. Instead of a producer method (see CDI-produces-disposes example) +a producer field can be used. A producer field can be used instead of a simple getter method. It could be used to +inject resources, such as persistence contexts. One caveat to using producer fields over producer + methods is that a @Disposes method cannot be used in conjunction with @Produces field. + +== ConsoleHandler + + +[source,java] +---- +package org.superbiz.cdi.produces.field; + +public class ConsoleHandler implements LogHandler { + + private String name; + + public ConsoleHandler(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void writeLog(String s) { + System.out.printf("##### Handler: %s, Writing to the console!\n", getName()); + } +} +---- + + +== DatabaseHandler + + +[source,java] +---- +package org.superbiz.cdi.produces.field; + +public class DatabaseHandler implements LogHandler { + + private String name; + + public DatabaseHandler(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void writeLog(String s) { + System.out.printf("##### Handler: %s, Writing to the database!\n", getName()); + // Use connection to write log to database + } +} +---- + + +== FileHandler + + +[source,java] +---- +package org.superbiz.cdi.produces.field; + +public class FileHandler implements LogHandler { + + private String name; + + public FileHandler(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void writeLog(String s) { + System.out.printf("##### Handler: %s, Writing to the file!\n", getName()); + // Write to log file + } +} +---- + + +== LogFactory + + package org.superbiz.cdi.produces.field; + + import javax.enterprise.inject.Produces; + + public class LogFactory { + + private int type = 2; + + @Produces + LogHandler handler; + + public LogFactory(){ + handler = getLogHandler(); + } + + public LogHandler getLogHandler() { + switch (type) { + case 1: + return new FileHandler("@Produces created FileHandler!"); + case 2: + return new DatabaseHandler("@Produces created DatabaseHandler!"); + case 3: + default: + return new ConsoleHandler("@Produces created ConsoleHandler!"); + } + + } + } + +== Logger + + +[source,java] +---- +package org.superbiz.cdi.produces.field; + +public interface Logger { + + public void log(String s); + + public LogHandler getHandler(); +} +---- + + +== LoggerImpl + + +[source,java] +---- +package org.superbiz.cdi.produces.field; + +import javax.inject.Inject; +import javax.inject.Named; + +@Named("logger") +public class LoggerImpl implements Logger { + + @Inject + private LogHandler handler; + + @Override + public void log(String s) { + getHandler().writeLog(s); + } + + public LogHandler getHandler() { + return handler; + } +} +---- + + +== LogHandler + + +[source,java] +---- +package org.superbiz.cdi.produces.field; + +public interface LogHandler { + + public String getName(); + + public void writeLog(String s); +} +---- + + +== beans.xml + + +[source,xml] +---- +<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee + http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> + +</beans> +---- + + +== LoggerTest + + +[source,java] +---- +package org.superbiz.cdi.produces.field; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.ejb.embeddable.EJBContainer; +import javax.inject.Inject; +import javax.naming.Context; + +import static junit.framework.Assert.assertNotNull; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class LoggerTest { + + @Inject + Logger logger; + + private Context ctxt; + + @Before + public void setUp() { + try { + ctxt = EJBContainer.createEJBContainer().getContext(); + ctxt.bind("inject", this); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @After + public void cleanUp() { + try { + ctxt.unbind("inject"); + ctxt.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testLogHandler() { + assertNotNull(logger); + assertFalse("Handler should not be a ConsoleHandler", logger.getHandler() instanceof ConsoleHandler); + assertFalse("Handler should not be a FileHandler", logger.getHandler() instanceof FileHandler); + assertTrue("Handler should be a DatabaseHandler", logger.getHandler() instanceof DatabaseHandler); + logger.log("##### Testing write\n"); + logger = null; + } + +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S + ------------------------------------------------------- + Running org.superbiz.cdi.produces.field.LoggerTest + INFO - ******************************************************************************** + INFO - OpenEJB http://tomee.apache.org/ + INFO - Startup: Thu May 10 01:28:19 CDT 2012 + INFO - Copyright 1999-2012 (C) Apache OpenEJB Project, All Rights Reserved. + INFO - Version: 7.0.0-SNAPSHOT + INFO - Build date: 20120510 + INFO - Build time: 04:06 + INFO - ******************************************************************************** + INFO - openejb.home = /home/daniel/projects/openejb/source/openejb/examples/cdi-produces-field + INFO - openejb.base = /home/daniel/projects/openejb/source/openejb/examples/cdi-produces-field + INFO - Created new singletonService org.apache.openejb.cdi.ThreadSingletonServiceImpl@a81b1fb + INFO - succeeded in installing singleton service + INFO - Using 'javax.ejb.embeddable.EJBContainer=true' + INFO - Cannot find the configuration file [conf/openejb.xml]. Will attempt to create one for the beans deployed. + INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) + INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) + INFO - Creating TransactionManager(id=Default Transaction Manager) + INFO - Creating SecurityService(id=Default Security Service) + INFO - Inspecting classpath for applications: 26 urls. Consider adjusting your exclude/include. Current settings: openejb.deployments.classpath.exclude='', openejb.deployments.classpath.include='.*' + INFO - Searched 26 classpath urls in 2015 milliseconds. Average 77 milliseconds per url. + INFO - Beginning load: /home/daniel/projects/openejb/source/openejb/examples/cdi-produces-field/target/classes + INFO - Configuring enterprise application: /home/daniel/projects/openejb/source/openejb/examples/cdi-produces-field + INFO - Auto-deploying ejb cdi-produces-field.Comp: EjbDeployment(deployment-id=cdi-produces-field.Comp) + INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) + INFO - Auto-creating a container for bean cdi-produces-field.Comp: Container(type=MANAGED, id=Default Managed Container) + INFO - Creating Container(id=Default Managed Container) + INFO - Using directory /tmp for stateful session passivation + INFO - Enterprise application "/home/daniel/projects/openejb/source/openejb/examples/cdi-produces-field" loaded. + INFO - Assembling app: /home/daniel/projects/openejb/source/openejb/examples/cdi-produces-field + INFO - ignoreXmlConfiguration == true + INFO - ignoreXmlConfiguration == true + INFO - existing thread singleton service in SystemInstance() org.apache.openejb.cdi.ThreadSingletonServiceImpl@a81b1fb + INFO - OpenWebBeans Container is starting... + INFO - Adding OpenWebBeansPlugin : [CdiPlugin] + INFO - All injection points were validated successfully. + INFO - OpenWebBeans Container has started, it took [69] ms. + INFO - Deployed Application(path=/home/daniel/projects/openejb/source/openejb/examples/cdi-produces-field) + ##### Handler: @Produces created DatabaseHandler!, Writing to the database! + INFO - Undeploying app: /home/daniel/projects/openejb/source/openejb/examples/cdi-produces-field + Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.79 sec + + Results : + + Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 + + http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-realm.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-realm.adoc b/src/main/jbake/content/examples/cdi-realm.adoc new file mode 100755 index 0000000..169d538 --- /dev/null +++ b/src/main/jbake/content/examples/cdi-realm.adoc @@ -0,0 +1,9 @@ += cdi-realm +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-realm can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-realm + +No README.md yet, be the first to contribute one! http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-request-scope.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-request-scope.adoc b/src/main/jbake/content/examples/cdi-request-scope.adoc new file mode 100755 index 0000000..2075109 --- /dev/null +++ b/src/main/jbake/content/examples/cdi-request-scope.adoc @@ -0,0 +1,182 @@ += CDI @RequestScoped +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-request-scope can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-request-scope + + +This example show the use of `@RequestScoped` annotation for injected objects. An object +which is defined as `@RequestScoped` is created once for every request and is shared by all the +bean that inject it throughout a request. + += Example + +This example depicts a similar scenario to cdi-application-scope. A restaurant guest orders +a soup from the waiter. The order is passed to the chef who prepares it and passes it back +the waiter who in turn delivers it to the guest. + +== Waiter + +The `Waiter` session bean receives a request from the test class via the `orderSoup()` method. +A `Soup` insance will be created in this method and will be shared throughout the request with +the `Chef` bean. The method passes the request to the `Chef` bean. It then returns the name of +the soup to the test class. + + +[source,java] +---- +@Stateless +public class Waiter { + + @Inject + private Soup soup; + + @EJB + private Chef chef; + + public String orderSoup(String name){ + soup.setName(name); + return chef.prepareSoup().getName(); + } +} +---- + + +== Soup + +The `Soup` class is an injectable POJO, defined as `@RequestScoped`. This means that an instance +will be created only once for every request and will be shared by all the beans injecting it. + + +[source,java] +---- +@RequestScoped +public class Soup { + + private String name = "Soup of the day"; + + @PostConstruct + public void afterCreate() { + System.out.println("Soup created"); + } + + public String getName() { + return name; + } + + public void setName(String name){ + this.name = name; + } +} +---- + + +== Chef + +The `Chef` class is a simple session bean with an injected `Soup` field. Normally, the soup +parameter would be passed as a `prepareSoup()` argument, but for the need of this example +it's passed by the request context. + + +[source,java] +---- +@Stateless +public class Chef { + + @Inject + private Soup soup; + + public Soup prepareSoup() { + return soup; + } +} +---- + + += Test Case + +This is the entry class for this example. + + +[source,java] +---- +public class RestaurantTest { + + private static String TOMATO_SOUP = "Tomato Soup"; + private EJBContainer container; + + @EJB + private Waiter joe; + + @Before + public void startContainer() throws Exception { + container = EJBContainer.createEJBContainer(); + container.getContext().bind("inject", this); + } + + @Test + public void orderSoup(){ + String soup = joe.orderSoup(TOMATO_SOUP); + assertEquals(TOMATO_SOUP, soup); + soup = joe.orderSoup(POTATO_SOUP); + assertEquals(POTATO_SOUP, soup); + } + + @After + public void closeContainer() throws Exception { + container.close(); + } +} +---- + + += Running + +In the output you can see that there were two `Soup` instances created - one for +each request. + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.cdi.requestscope.RestaurantTest +Apache OpenEJB 7.0.0-SNAPSHOT build: 20111224-11:09 +http://tomee.apache.org/ +INFO - openejb.home = C:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-request-scope +INFO - openejb.base = C:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-request-scope +INFO - Using 'javax.ejb.embeddable.EJBContainer=true' +INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Found EjbModule in classpath: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-request-scope\target\classes +INFO - Beginning load: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-request-scope\target\classes +INFO - Configuring enterprise application: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-request-scope +INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +INFO - Auto-creating a container for bean cdi-request-scope.Comp: Container(type=MANAGED, id=Default Managed Container) +INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) +INFO - Auto-creating a container for bean Chef: Container(type=STATELESS, id=Default Stateless Container) +INFO - Enterprise application "c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-request-scope" loaded. +INFO - Assembling app: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-request-scope +INFO - Jndi(name="java:global/cdi-request-scope/Chef!org.superbiz.cdi.requestscope.Chef") +INFO - Jndi(name="java:global/cdi-request-scope/Chef") +INFO - Jndi(name="java:global/cdi-request-scope/Waiter!org.superbiz.cdi.requestscope.Waiter") +INFO - Jndi(name="java:global/cdi-request-scope/Waiter") +INFO - Created Ejb(deployment-id=Chef, ejb-name=Chef, container=Default Stateless Container) +INFO - Created Ejb(deployment-id=Waiter, ejb-name=Waiter, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=Chef, ejb-name=Chef, container=Default Stateless Container) +INFO - Started Ejb(deployment-id=Waiter, ejb-name=Waiter, container=Default Stateless Container) +INFO - Deployed Application(path=c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-request-scope) +Soup created +Soup created +INFO - Undeploying app: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-request-scope +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.412 sec + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +---- + + http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cdi-session-scope.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cdi-session-scope.adoc b/src/main/jbake/content/examples/cdi-session-scope.adoc new file mode 100755 index 0000000..e783b50 --- /dev/null +++ b/src/main/jbake/content/examples/cdi-session-scope.adoc @@ -0,0 +1,9 @@ += cdi-session-scope +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cdi-session-scope can be browsed at https://github.com/apache/tomee/tree/master/examples/cdi-session-scope + +No README.md yet, be the first to contribute one! http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/change-jaxws-url.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/change-jaxws-url.adoc b/src/main/jbake/content/examples/change-jaxws-url.adoc new file mode 100755 index 0000000..cc44be8 --- /dev/null +++ b/src/main/jbake/content/examples/change-jaxws-url.adoc @@ -0,0 +1,116 @@ += Change JAXWS URL +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example change-jaxws-url can be browsed at https://github.com/apache/tomee/tree/master/examples/change-jaxws-url + + +*Help us document this example! Click the blue pencil icon in the upper right to edit this page.* + +To change a webservice deployment URI one solution is to use openejb-jar.xml. + +In this sample we have a webservice though the class Rot13: + + +[source,java] +---- +package org.superbiz.jaxws; + +import javax.ejb.Lock; +import javax.ejb.LockType; +import javax.ejb.Singleton; +import javax.jws.WebService; + +@Lock(LockType.READ) +@Singleton +@WebService +public class Rot13 { + public String rot13(final String in) { + final StringBuilder builder = new StringBuilder(in.length()); + for (int b : in.toCharArray()) { + int cap = b & 32; + b &= ~cap; + if (Character.isUpperCase(b)) { + b = (b - 'A' + 13) % 26 + 'A'; + } else { + b = cap; + } + b |= cap; + builder.append((char) b); + } + return builder.toString(); + } +} +---- + + +We decide to deploy to /tool/rot13 url. + +To do so we first define it in openejb-jar.xml: + + +[source,xml] +---- +<?xml version="1.0" encoding="UTF-8"?> +<openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.1"> + <enterprise-beans> + <session> + <ejb-name>Rot13</ejb-name> + <web-service-address>/tool/rot13</web-service-address> + </session> + </enterprise-beans> +</openejb-jar> +---- + + + +It is not enough since by default TomEE deploys the webservices in a subcontext called webservices. To skip it +simply set the system property tomee.jaxws.subcontext to / (done in arquillian.xml for our test). + +Then now our Rot13 webservice is deployed as expected to /tool/rot13 and we check it with arquillian and tomee embedded: + + package org.superbiz.jaxws; + + import org.apache.ziplock.IO; + import org.jboss.arquillian.container.test.api.Deployment; + import org.jboss.arquillian.junit.Arquillian; + import org.jboss.arquillian.test.api.ArquillianResource; + import org.jboss.shrinkwrap.api.ArchivePaths; + import org.jboss.shrinkwrap.api.ShrinkWrap; + import org.jboss.shrinkwrap.api.asset.ClassLoaderAsset; + import org.jboss.shrinkwrap.api.spec.WebArchive; + import org.junit.AfterClass; + import org.junit.BeforeClass; + import org.junit.Test; + import org.junit.runner.RunWith; + + import java.net.URL; + + import static org.junit.Assert.assertThat; + import static org.junit.internal.matchers.StringContains.containsString; + + @RunWith(Arquillian.class) + public class Rot13Test { + @ArquillianResource + private URL url; + + @Deployment(testable = false) + public static WebArchive war() { + return ShrinkWrap.create(WebArchive.class) + .addClass(Rot13.class) + .addAsWebInfResource(new ClassLoaderAsset("META-INF/openejb-jar.xml"), ArchivePaths.create("openejb-jar.xml")); + } + + @Test + public void checkWSDLIsDeployedWhereItIsConfigured() throws Exception { + final String wsdl = IO.slurp(new URL(url.toExternalForm() + "tool/rot13?wsdl")); + assertThat(wsdl, containsString("Rot13")); + } + } + + + + + http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/client-resource-lookup-preview.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/client-resource-lookup-preview.adoc b/src/main/jbake/content/examples/client-resource-lookup-preview.adoc new file mode 100755 index 0000000..a264a49 --- /dev/null +++ b/src/main/jbake/content/examples/client-resource-lookup-preview.adoc @@ -0,0 +1,9 @@ += client-resource-lookup-preview +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example client-resource-lookup-preview can be browsed at https://github.com/apache/tomee/tree/master/examples/client-resource-lookup-preview + +No README.md yet, be the first to contribute one! http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/component-interfaces.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/component-interfaces.adoc b/src/main/jbake/content/examples/component-interfaces.adoc new file mode 100755 index 0000000..accdf64 --- /dev/null +++ b/src/main/jbake/content/examples/component-interfaces.adoc @@ -0,0 +1,497 @@ += Component Interfaces +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example component-interfaces can be browsed at https://github.com/apache/tomee/tree/master/examples/component-interfaces + + +*Help us document this example! Click the blue pencil icon in the upper right to edit this page.* + +== FriendlyPerson + + +[source,java] +---- +package org.superbiz; + +import javax.ejb.Init; +import javax.ejb.Local; +import javax.ejb.LocalHome; +import javax.ejb.Remote; +import javax.ejb.RemoteHome; +import javax.ejb.Remove; +import javax.ejb.Stateful; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Locale; +import java.util.Properties; + +/** + * This is an EJB 3 style pojo stateful session bean + * it does not need to implement javax.ejb.SessionBean + * + */ +//START SNIPPET: code + +// EJB 3.0 Style business interfaces +// Each of these interfaces are already annotated in the classes +// themselves with @Remote and @Local, so annotating them here +// in the bean class again is not really required. +@Remote({FriendlyPersonRemote.class}) +@Local({FriendlyPersonLocal.class}) + +// EJB 2.1 Style component interfaces +// These interfaces, however, must be annotated here in the bean class. +// Use of @RemoteHome in the FriendlyPersonEjbHome class itself is not allowed. +// Use of @LocalHome in the FriendlyPersonEjbLocalHome class itself is also not allowed. +@RemoteHome(FriendlyPersonEjbHome.class) +@LocalHome(FriendlyPersonEjbLocalHome.class) + +@Stateful +public class FriendlyPerson implements FriendlyPersonLocal, FriendlyPersonRemote { + + private final HashMap<String, MessageFormat> greetings; + private final Properties languagePreferences; + + private String defaultLanguage; + + public FriendlyPerson() { + greetings = new HashMap(); + languagePreferences = new Properties(); + defaultLanguage = Locale.getDefault().getLanguage(); + + addGreeting("en", "Hello {0}!"); + addGreeting("es", "Hola {0}!"); + addGreeting("fr", "Bonjour {0}!"); + addGreeting("pl", "Witaj {0}!"); + } + + /** + * This method corresponds to the FriendlyPersonEjbHome.create() method + * and the FriendlyPersonEjbLocalHome.create() + * <p/> + * If you do not have an EJBHome or EJBLocalHome interface, this method + * can be deleted. + */ + @Init + public void create() { + } + + /** + * This method corresponds to the following methods: + * - EJBObject.remove() + * - EJBHome.remove(ejbObject) + * - EJBLocalObject.remove() + * - EJBLocalHome.remove(ejbObject) + * <p/> + * If you do not have an EJBHome or EJBLocalHome interface, this method + * can be deleted. + */ + @Remove + public void remove() { + } + + public String greet(String friend) { + String language = languagePreferences.getProperty(friend, defaultLanguage); + return greet(language, friend); + } + + public String greet(String language, String friend) { + MessageFormat greeting = greetings.get(language); + if (greeting == null) { + Locale locale = new Locale(language); + return "Sorry, I don't speak " + locale.getDisplayLanguage() + "."; + } + + return greeting.format(new Object[]{friend}); + } + + public void addGreeting(String language, String message) { + greetings.put(language, new MessageFormat(message)); + } + + public void setLanguagePreferences(String friend, String language) { + languagePreferences.put(friend, language); + } + + public String getDefaultLanguage() { + return defaultLanguage; + } + + public void setDefaultLanguage(String defaultLanguage) { + this.defaultLanguage = defaultLanguage; + } +} +---- + + +== FriendlyPersonEjbHome + + +[source,java] +---- +package org.superbiz; + +//START SNIPPET: code + +import javax.ejb.CreateException; +import javax.ejb.EJBHome; +import java.rmi.RemoteException; + +public interface FriendlyPersonEjbHome extends EJBHome { + FriendlyPersonEjbObject create() throws CreateException, RemoteException; +} +---- + + +== FriendlyPersonEjbLocalHome + + +[source,java] +---- +package org.superbiz; + +//START SNIPPET: code + +import javax.ejb.CreateException; +import javax.ejb.EJBLocalHome; +import java.rmi.RemoteException; + +public interface FriendlyPersonEjbLocalHome extends EJBLocalHome { + FriendlyPersonEjbLocalObject create() throws CreateException, RemoteException; +} +---- + + +== FriendlyPersonEjbLocalObject + + +[source,java] +---- +package org.superbiz; + +import javax.ejb.EJBLocalObject; + +public interface FriendlyPersonEjbLocalObject extends EJBLocalObject { + String greet(String friend); + + String greet(String language, String friend); + + void addGreeting(String language, String message); + + void setLanguagePreferences(String friend, String language); + + String getDefaultLanguage(); + + void setDefaultLanguage(String defaultLanguage); +} +---- + + +== FriendlyPersonEjbObject + + +[source,java] +---- +package org.superbiz; + +//START SNIPPET: code + +import javax.ejb.EJBObject; +import java.rmi.RemoteException; + +public interface FriendlyPersonEjbObject extends EJBObject { + String greet(String friend) throws RemoteException; + + String greet(String language, String friend) throws RemoteException; + + void addGreeting(String language, String message) throws RemoteException; + + void setLanguagePreferences(String friend, String language) throws RemoteException; + + String getDefaultLanguage() throws RemoteException; + + void setDefaultLanguage(String defaultLanguage) throws RemoteException; +} +---- + + +== FriendlyPersonLocal + + +[source,java] +---- +package org.superbiz; + +//START SNIPPET: code + +import javax.ejb.Local; + +@Local +public interface FriendlyPersonLocal { + String greet(String friend); + + String greet(String language, String friend); + + void addGreeting(String language, String message); + + void setLanguagePreferences(String friend, String language); + + String getDefaultLanguage(); + + void setDefaultLanguage(String defaultLanguage); +} +---- + + +== FriendlyPersonRemote + + +[source,java] +---- +package org.superbiz; + +import javax.ejb.Remote; + +//START SNIPPET: code +@Remote +public interface FriendlyPersonRemote { + String greet(String friend); + + String greet(String language, String friend); + + void addGreeting(String language, String message); + + void setLanguagePreferences(String friend, String language); + + String getDefaultLanguage(); + + void setDefaultLanguage(String defaultLanguage); +} +---- + + +== FriendlyPersonTest + + +[source,java] +---- +package org.superbiz; + +import junit.framework.TestCase; + +import javax.ejb.embeddable.EJBContainer; +import javax.naming.Context; +import java.util.Locale; + +/** + * @version $Rev: 1090810 $ $Date: 2011-04-10 07:49:26 -0700 (Sun, 10 Apr 2011) $ + */ +public class FriendlyPersonTest extends TestCase { + + private Context context; + + protected void setUp() throws Exception { + context = EJBContainer.createEJBContainer().getContext(); + } + + /** + * Here we lookup and test the FriendlyPerson bean via its EJB 2.1 EJBHome and EJBObject interfaces + * + * @throws Exception + */ + //START SNIPPET: remotehome + public void testEjbHomeAndEjbObject() throws Exception { + Object object = context.lookup("java:global/component-interfaces/FriendlyPerson!org.superbiz.FriendlyPersonEjbHome"); + FriendlyPersonEjbHome home = (FriendlyPersonEjbHome) object; + FriendlyPersonEjbObject friendlyPerson = home.create(); + + friendlyPerson.setDefaultLanguage("en"); + + assertEquals("Hello David!", friendlyPerson.greet("David")); + assertEquals("Hello Amelia!", friendlyPerson.greet("Amelia")); + + friendlyPerson.setLanguagePreferences("Amelia", "es"); + + assertEquals("Hello David!", friendlyPerson.greet("David")); + assertEquals("Hola Amelia!", friendlyPerson.greet("Amelia")); + + // Amelia took some French, let's see if she remembers + assertEquals("Bonjour Amelia!", friendlyPerson.greet("fr", "Amelia")); + + // Dave should take some Polish and if he had, he could say Hi in Polish + assertEquals("Witaj Dave!", friendlyPerson.greet("pl", "Dave")); + + // Let's see if I speak Portuguese + assertEquals("Sorry, I don't speak " + new Locale("pt").getDisplayLanguage() + ".", friendlyPerson.greet("pt", "David")); + + // Ok, well I've been meaning to learn, so... + friendlyPerson.addGreeting("pt", "Ola {0}!"); + + assertEquals("Ola David!", friendlyPerson.greet("pt", "David")); + } + //END SNIPPET: remotehome + + + /** + * Here we lookup and test the FriendlyPerson bean via its EJB 2.1 EJBLocalHome and EJBLocalObject interfaces + * + * @throws Exception + */ + public void testEjbLocalHomeAndEjbLocalObject() throws Exception { + Object object = context.lookup("java:global/component-interfaces/FriendlyPerson!org.superbiz.FriendlyPersonEjbLocalHome"); + FriendlyPersonEjbLocalHome home = (FriendlyPersonEjbLocalHome) object; + FriendlyPersonEjbLocalObject friendlyPerson = home.create(); + + friendlyPerson.setDefaultLanguage("en"); + + assertEquals("Hello David!", friendlyPerson.greet("David")); + assertEquals("Hello Amelia!", friendlyPerson.greet("Amelia")); + + friendlyPerson.setLanguagePreferences("Amelia", "es"); + + assertEquals("Hello David!", friendlyPerson.greet("David")); + assertEquals("Hola Amelia!", friendlyPerson.greet("Amelia")); + + // Amelia took some French, let's see if she remembers + assertEquals("Bonjour Amelia!", friendlyPerson.greet("fr", "Amelia")); + + // Dave should take some Polish and if he had, he could say Hi in Polish + assertEquals("Witaj Dave!", friendlyPerson.greet("pl", "Dave")); + + // Let's see if I speak Portuguese + assertEquals("Sorry, I don't speak " + new Locale("pt").getDisplayLanguage() + ".", friendlyPerson.greet("pt", "David")); + + // Ok, well I've been meaning to learn, so... + friendlyPerson.addGreeting("pt", "Ola {0}!"); + + assertEquals("Ola David!", friendlyPerson.greet("pt", "David")); + } + + /** + * Here we lookup and test the FriendlyPerson bean via its EJB 3.0 business remote interface + * + * @throws Exception + */ + //START SNIPPET: remote + public void testBusinessRemote() throws Exception { + Object object = context.lookup("java:global/component-interfaces/FriendlyPerson!org.superbiz.FriendlyPersonRemote"); + + FriendlyPersonRemote friendlyPerson = (FriendlyPersonRemote) object; + + friendlyPerson.setDefaultLanguage("en"); + + assertEquals("Hello David!", friendlyPerson.greet("David")); + assertEquals("Hello Amelia!", friendlyPerson.greet("Amelia")); + + friendlyPerson.setLanguagePreferences("Amelia", "es"); + + assertEquals("Hello David!", friendlyPerson.greet("David")); + assertEquals("Hola Amelia!", friendlyPerson.greet("Amelia")); + + // Amelia took some French, let's see if she remembers + assertEquals("Bonjour Amelia!", friendlyPerson.greet("fr", "Amelia")); + + // Dave should take some Polish and if he had, he could say Hi in Polish + assertEquals("Witaj Dave!", friendlyPerson.greet("pl", "Dave")); + + // Let's see if I speak Portuguese + assertEquals("Sorry, I don't speak " + new Locale("pt").getDisplayLanguage() + ".", friendlyPerson.greet("pt", "David")); + + // Ok, well I've been meaning to learn, so... + friendlyPerson.addGreeting("pt", "Ola {0}!"); + + assertEquals("Ola David!", friendlyPerson.greet("pt", "David")); + } + //START SNIPPET: remote + + /** + * Here we lookup and test the FriendlyPerson bean via its EJB 3.0 business local interface + * + * @throws Exception + */ + public void testBusinessLocal() throws Exception { + Object object = context.lookup("java:global/component-interfaces/FriendlyPerson!org.superbiz.FriendlyPersonLocal"); + + FriendlyPersonLocal friendlyPerson = (FriendlyPersonLocal) object; + + friendlyPerson.setDefaultLanguage("en"); + + assertEquals("Hello David!", friendlyPerson.greet("David")); + assertEquals("Hello Amelia!", friendlyPerson.greet("Amelia")); + + friendlyPerson.setLanguagePreferences("Amelia", "es"); + + assertEquals("Hello David!", friendlyPerson.greet("David")); + assertEquals("Hola Amelia!", friendlyPerson.greet("Amelia")); + + // Amelia took some French, let's see if she remembers + assertEquals("Bonjour Amelia!", friendlyPerson.greet("fr", "Amelia")); + + // Dave should take some Polish and if he had, he could say Hi in Polish + assertEquals("Witaj Dave!", friendlyPerson.greet("pl", "Dave")); + + // Let's see if I speak Portuguese + assertEquals("Sorry, I don't speak " + new Locale("pt").getDisplayLanguage() + ".", friendlyPerson.greet("pt", "David")); + + // Ok, well I've been meaning to learn, so... + friendlyPerson.addGreeting("pt", "Ola {0}!"); + + assertEquals("Ola David!", friendlyPerson.greet("pt", "David")); + } + +} +---- + + += Running + + + +[source] +---- +------------------------------------------------------- + T E S T S +------------------------------------------------------- +Running org.superbiz.FriendlyPersonTest +Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 +http://tomee.apache.org/ +INFO - openejb.home = /Users/dblevins/examples/component-interfaces +INFO - openejb.base = /Users/dblevins/examples/component-interfaces +INFO - Using 'javax.ejb.embeddable.EJBContainer=true' +INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) +INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) +INFO - Found EjbModule in classpath: /Users/dblevins/examples/component-interfaces/target/classes +INFO - Beginning load: /Users/dblevins/examples/component-interfaces/target/classes +INFO - Configuring enterprise application: /Users/dblevins/examples/component-interfaces +INFO - Configuring Service(id=Default Stateful Container, type=Container, provider-id=Default Stateful Container) +INFO - Auto-creating a container for bean FriendlyPerson: Container(type=STATEFUL, id=Default Stateful Container) +INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) +INFO - Auto-creating a container for bean org.superbiz.FriendlyPersonTest: Container(type=MANAGED, id=Default Managed Container) +INFO - Enterprise application "/Users/dblevins/examples/component-interfaces" loaded. +INFO - Assembling app: /Users/dblevins/examples/component-interfaces +INFO - Jndi(name="java:global/component-interfaces/FriendlyPerson!org.superbiz.FriendlyPersonLocal") +INFO - Jndi(name="java:global/component-interfaces/FriendlyPerson!org.superbiz.FriendlyPersonRemote") +INFO - Jndi(name="java:global/component-interfaces/FriendlyPerson!org.superbiz.FriendlyPersonEjbLocalHome") +INFO - Jndi(name="java:global/component-interfaces/FriendlyPerson!org.superbiz.FriendlyPersonEjbHome") +INFO - Jndi(name="java:global/component-interfaces/FriendlyPerson") +INFO - Jndi(name="java:global/EjbModule803660549/org.superbiz.FriendlyPersonTest!org.superbiz.FriendlyPersonTest") +INFO - Jndi(name="java:global/EjbModule803660549/org.superbiz.FriendlyPersonTest") +INFO - Created Ejb(deployment-id=FriendlyPerson, ejb-name=FriendlyPerson, container=Default Stateful Container) +INFO - Created Ejb(deployment-id=org.superbiz.FriendlyPersonTest, ejb-name=org.superbiz.FriendlyPersonTest, container=Default Managed Container) +INFO - Started Ejb(deployment-id=FriendlyPerson, ejb-name=FriendlyPerson, container=Default Stateful Container) +INFO - Started Ejb(deployment-id=org.superbiz.FriendlyPersonTest, ejb-name=org.superbiz.FriendlyPersonTest, container=Default Managed Container) +INFO - Deployed Application(path=/Users/dblevins/examples/component-interfaces) +INFO - EJBContainer already initialized. Call ejbContainer.close() to allow reinitialization +INFO - EJBContainer already initialized. Call ejbContainer.close() to allow reinitialization +INFO - EJBContainer already initialized. Call ejbContainer.close() to allow reinitialization +Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.444 sec + +Results : + +Tests run: 4, Failures: 0, Errors: 0, Skipped: 0 +---- + + http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/972cc356/src/main/jbake/content/examples/cucumber-jvm.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/cucumber-jvm.adoc b/src/main/jbake/content/examples/cucumber-jvm.adoc new file mode 100755 index 0000000..69da1df --- /dev/null +++ b/src/main/jbake/content/examples/cucumber-jvm.adoc @@ -0,0 +1,9 @@ += cucumber-jvm +:jbake-date: 2016-09-06 +:jbake-type: page +:jbake-tomeepdf: +:jbake-status: published + +Example cucumber-jvm can be browsed at https://github.com/apache/tomee/tree/master/examples/cucumber-jvm + +No README.md yet, be the first to contribute one!