Playx :: Demo

Some integration of Servlet/CDI specifications into Play! framework.

License

License

GroupId

GroupId

com.github.rmannibucau
ArtifactId

ArtifactId

demo
Last Version

Last Version

0.0.14
Release Date

Release Date

Type

Type

pom
Description

Description

Playx :: Demo
Some integration of Servlet/CDI specifications into Play! framework.

Download demo

Filename Size
demo-0.0.14.pom 573 bytes
Browse

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.rmannibucau/demo/ -->
<dependency>
    <groupId>com.github.rmannibucau</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.14</version>
    <type>pom</type>
</dependency>
// https://jarcasting.com/artifacts/com.github.rmannibucau/demo/
implementation 'com.github.rmannibucau:demo:0.0.14'
// https://jarcasting.com/artifacts/com.github.rmannibucau/demo/
implementation ("com.github.rmannibucau:demo:0.0.14")
'com.github.rmannibucau:demo:pom:0.0.14'
<dependency org="com.github.rmannibucau" name="demo" rev="0.0.14">
  <artifact name="demo" type="pom" />
</dependency>
@Grapes(
@Grab(group='com.github.rmannibucau', module='demo', version='0.0.14')
)
libraryDependencies += "com.github.rmannibucau" % "demo" % "0.0.14"
[com.github.rmannibucau/demo "0.0.14"]

Dependencies

provided (1)

Group / Artifact Type Version
com.typesafe.play : play_2.12 jar 2.6.13

test (3)

Group / Artifact Type Version
com.typesafe.play : play-test_2.12 jar 2.6.13
com.typesafe.play : play-guice_2.12 jar 2.6.13
junit : junit jar 4.12

Project Modules

  • demo-jaxrs

Playx

Bring some of Javax to Play!

Servlet

<dependency>
    <groupId>com.github.rmannibucau</groupId>
    <artifactId>playx-servlet</artifactId>
    <version>${playx.version}</version>
</dependency>

Servlet integration brings the ability to use play as a servlet container.

Setup:

  1. Bind a PlayServletContext in your IoC to let ServletFilter get injected - we assume you are using Guice here:

public class ServletModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(PlayServletContext.class);
        bind(PlayServletContext.class).toInstance(servletContext);
    }
}
  1. You can bind servlets to the context using a ServletContainerInitializer or directly defining servlets. To use an initializer, register it through the related config entry;:

playx.servlet.initializers += org.app.MyInitializer

An implementation can look like:

public class Setup implements ServletContainerInitializer {
    @Override
    public void onStartup(final Set<Class<?>> c, final ServletContext servletContext) {
        {
            final ServletRegistration.Dynamic servlet = servletContext.addServlet("async", new AsyncServlet());
            servlet.addMapping("/async");
            servlet.setAsyncSupported(true);
        }
        {
            final ServletRegistration.Dynamic servlet = servletContext.addServlet("asyncdispatch",
                    new AsyncDispatchServlet());
            servlet.addMapping("/asyncdispatch");
            servlet.setAsyncSupported(true);
        }
        {
            servletContext.addServlet("sync", new SyncServlet()).addMapping("/sync");
        }
    }
}
  1. Bind the ServletFilter in your configuration, this is the one responsible to route the requests to the servlet context when relevant (depending the mapping):

play.filters.enabled.1000 = com.github.rmannibucau.playx.servlet.servlet.api.ServletFilter
Important
the number at the end is the position of the filter in the list, it is highly recommanded to put it last since it acts as an endpoint and must stay after security filters when in use, if you use a custom DefaultFilters ensure it is at the last position.

Known limitations

  1. No filter support (yet)

  2. No WebListener support (yet)

  3. HandlesTypes is not supported yet

Configuration

playx {
  servlet {
    context = "" // the servlet context to use, default is root

    executor { // configure the pool used for the servlet operation
      core = 64 // when default = false it is the core size of the pool
      max = 128 // when default = false it is the max size of the pool
      keepAlive { // how long a thread is kept idle in the pool
        value = 60
        unit = SECONDS
      }
    }

    initializers = [
      org.app.Initializer
    ]

    listeners = [
      app.MyContextListener
    ]

    filters = [
      {
        name: "my-fitler",
        className: "my.FilterImpl",
        asyncSupported: true,
        initParameters: [
          { name: "the key", value: "the value" }
        ]
      }
    ]

    servlets = [
      {
        name: "my-servlet",
        className: "my.ServletImpl",
        asyncSupported: true,
        loadOnStartup: 1,
        initParameters: [
          { name: "the key", value: "the value" }
        ]
      }
    ]
  }
}

IoC

<dependency>
    <groupId>com.github.rmannibucau</groupId>
    <artifactId>playx-ioc</artifactId>
    <version>${playx.version}</version>
</dependency>

This module provides some way to setup a generic IoC and delegate the logic to multiple implementations.

Configuration

// force play to use the playx implementation
play.application.loader = com.github.rmannibucau.playx.ioc.IoCLoader

// configure the loaders to use
playx {
  ioc {
    loaders = [
      play.inject.guice.GuiceApplicationLoader,
      my.container.MyApplicationLoader
    ]
    // you can specify a preference for the IoC by package
    // the key is the package (subpackages are included) and the value
    // a string contained in the lowercased loader simple name (must not be ambiguous)
    routing = [
        { "org.superbiz": "guice" },
        { "com.app": "my" }
    ]
  }
}

The Application loaded by the IoCLoader will be the first one in the list.

CDI

<dependency>
    <groupId>com.github.rmannibucau</groupId>
    <artifactId>playx-cdi</artifactId>
    <version>${playx.version}</version>
</dependency>

The CDI module allows to start a CDI 2.0 standalone container and use it either with ioc module or just as a contextual CDI (i.e. not linked to play IoC but embedded in play).

Important
the play IoC model being very tight to Guice due its module definition which is not supported yet in CDI integration, you can need to define some play beans to use it as the main and unique loader for your application.

This module doesn’t provide any CDI API not implementation to let you plug the one you prefer (Apache OpenWebBeans is recommanded since default setup is done for play but Weld works too). The dependency to add is the CDI SE module (openwebbeans-se for instance).

Warning
since generally applications rely on a Guice version of the play JSR-330 integration and since CDI scanning works great without that boilerplate, there is not yet a conversion of modules. However if you are interested in supporting play.modules.enabled you can write a custom CDI extension to do it.

Configuration

Check out the javax.enterprise.inject.se.SeContainerInitializer API for the meaning of each configuration entry.

play.application.loader = com.github.rmannibucau.playx.cdi.CdiLoader

playx {
  cdi {
    // same as play.allowGlobalApplication but for this IoC
    allowGlobalApplication = false

    beans { // should default play bean be added to CDI context
      default = true

      // provides a way to register custom beans, useful for not scanned modules
      customs = [
        // only className is mandatory
        {
          className: org.foo.MyBean,
          scope: "javax.enterprise.context.Dependent",
          id: "custom.org.foo.MyBean",
          transitiveTypeClosure: false
        }
      ]
    }

    container { // all is optional
      disableDiscovery = false,
      beanClasses = [
        com.app.Foo,
        com.app.Bar
      ],
      packages = [
        org.superbiz, // shortcut for next line syntax with recursive=false
        { package: "org.apache.deltaspike", recursive: true }
      ],
      properties = [ // mainly vendor specific
        { key: "foo", value: "bar" }
      ],
      extensions = [
        org.apache.deltaspike.core.api.provider.BeanManagerProvider,
        org.apache.deltaspike.core.impl.config.ConfigurationExtension,
        org.apache.deltaspike.core.impl.jmx.MBeanExtension,
        org.apache.johnzon.jsonb.cdi.JohnzonCdiExtension
      ],
      decorators = [
        org.app.MyDecorator
      ],
      interceptor = [
        org.app.MyInterceptor
      ],
      alternatives = [
        org.app.MyAlternative
      ],
      alternativeStereotypes = [
        org.app.MyStereotype
      ]
  }
}

Microprofile Config

<dependency>
    <groupId>com.github.rmannibucau</groupId>
    <artifactId>playx-microprofile-config</artifactId>
    <version>${playx.version}</version>
</dependency>

This module adds a Microprofile Configuration ConfigSource using CDI to look up a typesafe Config to get configurations. It support primitives, objects and list of primitives (but not list of object) and flatten the configuration keys.

For instance:

app {
  service {
    url = "http://remote"
  }
}

Will provide the following configurations:

app.service.url = http://remote

So you can use it through:

@Inject
@ConfigProperty(name = "app.service.url")
private String url;

Swagger Integration

<dependency>
    <groupId>com.github.rmannibucau</groupId>
    <artifactId>playx-swagger</artifactId>
    <version>${playx.version}</version>
</dependency>

Playx Swagger extends play-swagger module to support to enrich swagger with custom swagger readers. It requires to provide a reader class with a read(Set<Class<?>>) method and taking a Swagger instance in its constructor.

swagger.api.additional = [
    {
        reader: "io.swagger.jaxrs.Reader",
        prefix: "/api", // prefixes all operation paths, default to empty
        classes: [
            "app.MyJaxRsEndpoint1",
            "app.MyJaxRsEndpoint2",
            "app.MyJaxRsEndpoint3"
        ]
    }
]

Versions

Version
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1