diff --git a/jee-kotlin/README.md b/jee-kotlin/README.md
new file mode 100644
index 0000000000..7d843af9ea
--- /dev/null
+++ b/jee-kotlin/README.md
@@ -0,0 +1 @@
+### Relevant Articles:
diff --git a/jee-kotlin/pom.xml b/jee-kotlin/pom.xml
new file mode 100644
index 0000000000..963c03d0df
--- /dev/null
+++ b/jee-kotlin/pom.xml
@@ -0,0 +1,289 @@
+
+
+
+ 4.0.0
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
+
+ jee-kotlin
+ jee-kotlin
+ war
+
+
+ UTF-8
+ false
+ 8.0
+
+
+ 1.3.41
+ official
+ true
+
+
+ 8.2.1.Final
+ 3.2.3
+ 2.21.0
+ 3.1.1
+
+ 1.4.1.Final
+ 2.0.1.Final
+ 1.0.0.Alpha4
+
+ 4.12
+ 3.8.0.Final
+ 2.9.8
+ 3.1.3
+
+
+
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib-jdk8
+ ${kotlin.version}
+
+
+ org.jetbrains.kotlin
+ kotlin-test-junit
+ ${kotlin.version}
+ test
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+ javax
+ javaee-api
+ ${javaee-api.version}
+ jar
+ provided
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+ test
+
+
+ org.jboss.arquillian.junit
+ arquillian-junit-container
+ ${arquillian_core.version}
+ test
+
+
+ org.jboss.shrinkwrap.resolver
+ shrinkwrap-resolver-depchain
+ ${shrinkwrap.version}
+ pom
+ test
+
+
+ org.jboss.arquillian.extension
+ arquillian-rest-client-impl-jersey
+ ${arquillian-rest-client.version}
+
+
+ org.jetbrains.kotlin
+ kotlin-test
+ ${kotlin.version}
+ test
+
+
+
+
+ src/main/kotlin
+ src/test/kotlin
+
+
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${kotlin.version}
+
+
+ compile
+ compile
+
+ compile
+
+
+
+ test-compile
+ test-compile
+
+ test-compile
+
+
+
+
+ 1.8
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ ${mvn-war-plugin.version}
+
+ webapp
+ kotlin
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ default-compile
+ none
+
+
+ default-testCompile
+ none
+
+
+ compile
+ compile
+
+ compile
+
+
+
+ testCompile
+ test-compile
+
+ testCompile
+
+
+
+
+
+
+
+
+
+
+ org.jboss.arquillian
+ arquillian-bom
+ ${arquillian_core.version}
+ import
+ pom
+
+
+ org.jboss.arquillian.extension
+ arquillian-drone-bom
+ ${arquillian-drone-bom.version}
+ pom
+ import
+
+
+
+
+
+
+ wildfly-managed-arquillian
+
+ true
+
+
+
+ org.wildfly
+ wildfly-arquillian-container-embedded
+ ${wildfly.version}
+
+
+ org.wildfly
+ wildfly-embedded
+ ${wildfly.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ ${maven-dependency-plugin.version}
+
+
+ unpack
+ process-test-classes
+
+ unpack
+
+
+
+
+ org.wildfly
+ wildfly-dist
+ ${wildfly.version}
+ zip
+ false
+ target
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ always
+
+ org.jboss.logmanager.LogManager
+ ${project.basedir}/target/wildfly-${wildfly.version}
+ ${project.basedir}/target/wildfly-${wildfly.version}/modules
+
+ false
+
+
+
+
+
+
+ wildfly-remote-arquillian
+
+
+ org.jboss.resteasy
+ resteasy-client
+ ${resteasy.version}
+ test
+
+
+ org.jboss.resteasy
+ resteasy-jaxb-provider
+ ${resteasy.version}
+ test
+
+
+ org.jboss.resteasy
+ resteasy-json-p-provider
+ ${resteasy.version}
+ test
+
+
+ org.wildfly.arquillian
+ wildfly-arquillian-container-remote
+ 2.2.0.Final
+ test
+
+
+
+
+
diff --git a/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/entity/Student.kt b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/entity/Student.kt
new file mode 100644
index 0000000000..07f54a39d1
--- /dev/null
+++ b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/entity/Student.kt
@@ -0,0 +1,22 @@
+package com.baeldung.jeekotlin.entity
+
+import com.fasterxml.jackson.annotation.JsonProperty
+import javax.persistence.*
+
+@Entity
+data class Student constructor (
+
+ @SequenceGenerator(name = "student_id_seq", sequenceName = "student_id_seq", allocationSize = 1)
+ @GeneratedValue(generator = "student_id_seq", strategy = GenerationType.SEQUENCE)
+ @Id
+ var id: Long?,
+
+ var firstName: String,
+
+ var lastName: String
+
+) {
+ constructor() : this(null, "", "")
+
+ constructor(firstName: String, lastName: String) : this(null, firstName, lastName)
+}
diff --git a/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/ApplicationConfig.kt b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/ApplicationConfig.kt
new file mode 100644
index 0000000000..12511ed320
--- /dev/null
+++ b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/ApplicationConfig.kt
@@ -0,0 +1,9 @@
+package com.baeldung.jeekotlin.rest
+
+import javax.ws.rs.ApplicationPath
+import javax.ws.rs.core.Application
+
+@ApplicationPath("/")
+class ApplicationConfig : Application() {
+ override fun getClasses() = setOf(StudentResource::class.java)
+}
diff --git a/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/StudentResource.kt b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/StudentResource.kt
new file mode 100644
index 0000000000..91fa3ff62b
--- /dev/null
+++ b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/StudentResource.kt
@@ -0,0 +1,42 @@
+package com.baeldung.jeekotlin.rest
+
+import com.baeldung.jeekotlin.entity.Student
+import com.baeldung.jeekotlin.service.StudentService
+import javax.inject.Inject
+import javax.ws.rs.*
+import javax.ws.rs.core.MediaType
+import javax.ws.rs.core.Response
+
+@Path("/student")
+open class StudentResource {
+
+ @Inject
+ private lateinit var service: StudentService
+
+ @POST
+ open fun create(student: Student): Response {
+ service.create(student)
+ return Response.ok().build()
+ }
+
+ @GET
+ @Path("/{id}")
+ open fun read(@PathParam("id") id: Long): Response {
+ val student = service.read(id)
+ return Response.ok(student, MediaType.APPLICATION_JSON_TYPE).build()
+ }
+
+ @PUT
+ open fun update(student: Student): Response {
+ service.update(student)
+ return Response.ok(student, MediaType.APPLICATION_JSON_TYPE).build()
+ }
+
+ @DELETE
+ @Path("/{id}")
+ open fun delete(@PathParam("id") id: Long): Response {
+ service.delete(id)
+ return Response.noContent().build()
+ }
+
+}
\ No newline at end of file
diff --git a/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/service/StudentService.kt b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/service/StudentService.kt
new file mode 100644
index 0000000000..3977a45e96
--- /dev/null
+++ b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/service/StudentService.kt
@@ -0,0 +1,21 @@
+package com.baeldung.jeekotlin.service
+
+import com.baeldung.jeekotlin.entity.Student
+import javax.ejb.Stateless
+import javax.persistence.EntityManager
+import javax.persistence.PersistenceContext
+
+@Stateless
+open class StudentService {
+
+ @PersistenceContext
+ private lateinit var entityManager: EntityManager
+
+ open fun create(student: Student) = entityManager.persist(student)
+
+ open fun read(id: Long): Student? = entityManager.find(Student::class.java, id)
+
+ open fun update(student: Student) = entityManager.merge(student)
+
+ open fun delete(id: Long) = entityManager.remove(read(id))
+}
\ No newline at end of file
diff --git a/jee-kotlin/src/main/resources/META-INF/persistence.xml b/jee-kotlin/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000000..daac86868b
--- /dev/null
+++ b/jee-kotlin/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ org.hibernate.jpa.HibernatePersistenceProvider
+
+ java:jboss/datasources/ExampleDS
+
+ com.enpy.entity.Student
+
+
+
+
+
+
+
+
diff --git a/jee-kotlin/src/main/webapp/WEB-INF/beans.xml b/jee-kotlin/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000000..ae0f4bf2ee
--- /dev/null
+++ b/jee-kotlin/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/jee-kotlin/src/test/kotlin/com/baeldung/jeekotlin/StudentResourceIntegrationTest.java b/jee-kotlin/src/test/kotlin/com/baeldung/jeekotlin/StudentResourceIntegrationTest.java
new file mode 100644
index 0000000000..b91b47cb1f
--- /dev/null
+++ b/jee-kotlin/src/test/kotlin/com/baeldung/jeekotlin/StudentResourceIntegrationTest.java
@@ -0,0 +1,108 @@
+package com.baeldung.jeekotlin;
+
+import com.baeldung.jeekotlin.entity.Student;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Filters;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Arquillian.class)
+public class StudentResourceIntegrationTest {
+
+ @Deployment
+ public static WebArchive createDeployment() {
+ JavaArchive[] kotlinRuntime = Maven.configureResolver()
+ .workOffline()
+ .withMavenCentralRepo(true)
+ .withClassPathResolution(true)
+ .loadPomFromFile("pom.xml")
+ .resolve("org.jetbrains.kotlin:kotlin-stdlib")
+ .withTransitivity()
+ .as(JavaArchive.class);
+
+ return ShrinkWrap.create(WebArchive.class, "kotlin.war")
+ .addPackages(true, Filters.exclude(".*Test*"),
+ "com.baeldung.jeekotlin"
+ )
+ .addAsLibraries(kotlinRuntime)
+ .addAsResource("META-INF/persistence.xml")
+ .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
+ }
+
+ @Test
+ @RunAsClient
+ public void when_post__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
+ String student = new ObjectMapper().writeValueAsString(new Student("firstName", "lastName"));
+ WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
+
+ Response response = webTarget
+ .path("/student")
+ .request(MediaType.APPLICATION_JSON)
+ .post(Entity.json(student));
+
+ assertEquals(200, response.getStatus());
+ }
+
+ @Test
+ @RunAsClient
+ public void when_get__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
+ WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
+
+ Response response = webTarget
+ .path("/student/1")
+ .request(MediaType.APPLICATION_JSON)
+ .get();
+
+ assertEquals(200, response.getStatus());
+ }
+
+ @Test
+ @RunAsClient
+ public void when_put__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
+ Student student = new Student("firstName", "lastName");
+ student.setId(1L);
+ String studentJson = new ObjectMapper().writeValueAsString(student);
+ WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
+
+ Response response = webTarget
+ .path("/student")
+ .request(MediaType.APPLICATION_JSON)
+ .put(Entity.json(studentJson));
+
+ assertEquals(200, response.getStatus());
+ }
+
+ @Test
+ @RunAsClient
+ public void when_delete__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
+ WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
+
+ Response response = webTarget
+ .path("/student/1")
+ .request()
+ .delete();
+
+ assertEquals(204, response.getStatus());
+ }
+
+}
\ No newline at end of file
diff --git a/jee-kotlin/src/test/resources/arquillian.xml b/jee-kotlin/src/test/resources/arquillian.xml
new file mode 100644
index 0000000000..5e6d7c54e8
--- /dev/null
+++ b/jee-kotlin/src/test/resources/arquillian.xml
@@ -0,0 +1,22 @@
+
+
+
+
+ target/wildfly-8.2.1.Final
+ standalone.xml
+ true
+ 9990
+
+
+
+
+
+ 127.0.0.1
+ 9990
+ admin
+ pass
+ true
+
+
+
+
\ No newline at end of file