Intro
I will try running my Micronaut application on Tomcat in this time.
At first, I tried to access SQL Server using Micronaut R2DBC, as in previous blog posts.
- [Micronaut] Accessing SQL Server 1
- [Micronaut] Accessing SQL Server 2
- [Micronaut] Accessing SQL Server 3
But I couldn't figure out how to use the DataSource what is gotten from JNDI, so I decided to use Doma2.
I install Tomcat ver.10.1.18 on Fedora 39 first.
- Apache Tomcat 10(10.1.18) - Documentation Index
- Fedora 36にTomcat9.0.63をインストールする方法 - 最新IT技術情報_arkgame.com
Generating a war file and running on Tomcat
To generate a war file and run on Tomcat, I change "build.gradle".
build.gradle.kts
plugins {
id("com.github.johnrengelman.shadow") version "8.1.1"
id("io.micronaut.application") version "4.2.1"
id("io.micronaut.aot") version "4.2.1"
// add this
id("war")
}
...
graalvmNative.toolchainDetection.set(false)
micronaut {
// change from "netty"
runtime("tomcat")
testRuntime("junit5")
processing {
incremental(true)
annotations("jp.masanori.*")
}
aot {
optimizeServiceLoading.set(false)
convertYamlToJava.set(false)
precomputeOperations.set(true)
cacheEnvironment.set(true)
optimizeClassLoading.set(true)
deduceEnvironment.set(true)
optimizeNetty.set(true)
}
}
After that, I can generate a war file by "./gradlew war".
The generated war file is put into "{ProjectFolder}/build/libs".
To install into Tomcat, I move the war file into "/opt/tomcat/webapps".
Now, I can access the application on "http://localhost:8080/domasample".
(The file what I put is named "domasample.war")
Adding and getting JNDI
To get connection strings from JNDI, I add some strings into "context.xml" and "server.xml" of Tomcat.
context.xml
...
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<ResourceLink name="jdbc/mssql"
global="jdbc/mssql"
auth="Container"
type="javax.sql.DataSource" />
</Context>
server.xml
...
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
<Resource name="jdbc/mssql" auth="Container"
type="javax.sql.DataSource"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://localhost:1433;encrypt=false;DatabaseName=master"
username="sa"
password="example" />
</GlobalNamingResources>
...
And I can get JNDI data as DataSource like below.
import javax.sql.DataSource;
import javax.naming.InitialContext;
import javax.naming.NamingException;
...
try {
DataSource dataSource = (DataSource)(new InitialContext()).lookup("java:/comp/env/jdbc/mssql");
}catch(NamingException e) {
}
...
The problem was I couldn't figure out how to use the DataSource into R2DBC.
"application.yml(application.properties)" has "datasources.*.jndi-name".
But after I set the JNDI name, I couldn't connect.
Using Doma2
In this time, I have only confirmed that Doma2 can connect to SQL Server.
I'll look into it a little more closely next time.
build.gradle.kts
plugins {
id("com.github.johnrengelman.shadow") version "8.1.1"
id("io.micronaut.application") version "4.2.1"
id("io.micronaut.aot") version "4.2.1"
id("war")
}
version = "0.1"
group = "jp.masanori"
repositories {
mavenCentral()
}
dependencies {
annotationProcessor("org.projectlombok:lombok")
annotationProcessor("io.micronaut:micronaut-http-validation")
annotationProcessor("io.micronaut.serde:micronaut-serde-processor")
annotationProcessor("org.seasar.doma:doma-processor:2.55.2")
implementation("io.micronaut.serde:micronaut-serde-jackson")
implementation("org.seasar.doma:doma-core:2.55.2")
compileOnly("io.micronaut:micronaut-http-client")
compileOnly("org.projectlombok:lombok")
runtimeOnly("ch.qos.logback:logback-classic")
runtimeOnly("com.microsoft.sqlserver:mssql-jdbc")
testImplementation("io.micronaut:micronaut-http-client")
}
application {
mainClass.set("jp.masanori.Application")
}
java {
sourceCompatibility = JavaVersion.toVersion("17")
targetCompatibility = JavaVersion.toVersion("17")
}
graalvmNative.toolchainDetection.set(false)
micronaut {
runtime("tomcat")
testRuntime("junit5")
processing {
incremental(true)
annotations("jp.masanori.*")
}
aot {
optimizeServiceLoading.set(false)
convertYamlToJava.set(false)
precomputeOperations.set(true)
cacheEnvironment.set(true)
optimizeClassLoading.set(true)
deduceEnvironment.set(true)
optimizeNetty.set(true)
}
}
User.java
package jp.masanori.users.models;
import java.time.LocalDateTime;
import org.seasar.doma.Column;
import org.seasar.doma.Entity;
import org.seasar.doma.Id;
import org.seasar.doma.Table;
import io.micronaut.serde.annotation.Serdeable;
import lombok.Getter;
import lombok.Setter;
@Serdeable
@Entity
@Table(name = "users")
public class User {
@Id
@Getter
@Setter
public Long id;
@Getter
@Setter
public String name;
@Getter
@Setter
@Column(name = "last_update_date")
public LocalDateTime lastUpdateDate;
}
UserDao.java
package jp.masanori.users.dao;
import org.seasar.doma.Dao;
import org.seasar.doma.Select;
import org.seasar.doma.Sql;
import jp.masanori.DaoConfig;
import jp.masanori.users.models.User;
@Dao
@DaoConfig
public interface UserDao {
@Select
@Sql("SELECT * FROM users WHERE id = /*userId*/0")
User findById(Long userId);
}
DaoConfig.java
package jp.masanori;
import org.seasar.doma.AnnotateWith;
import org.seasar.doma.Annotation;
import org.seasar.doma.AnnotationTarget;
import jakarta.inject.Singleton;
@AnnotateWith(annotations = @Annotation(target = AnnotationTarget.CLASS, type = Singleton.class))
public @interface DaoConfig {
}
DomaConfig.java
package jp.masanori;
import javax.sql.DataSource;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.seasar.doma.jdbc.Config;
import org.seasar.doma.jdbc.dialect.Dialect;
import org.seasar.doma.jdbc.dialect.MssqlDialect;
import org.seasar.doma.jdbc.tx.LocalTransactionDataSource;
import org.seasar.doma.jdbc.tx.LocalTransactionManager;
import org.seasar.doma.jdbc.tx.TransactionManager;
import jakarta.inject.Singleton;
@Singleton
public class DomaConfig implements Config {
private final LocalTransactionDataSource dataSource;
private final LocalTransactionManager transactionManager;
public DomaConfig() {
LocalTransactionDataSource dataSource;
try {
dataSource = new LocalTransactionDataSource((DataSource)(new InitialContext()).lookup("java:/comp/env/jdbc/mssql"));
}catch(NamingException e) {
dataSource = new LocalTransactionDataSource("jdbc:sqlserver://localhost:1433;encrypt=false;databaseName=master;", "sa", "example");
}
this.dataSource = dataSource;
this.transactionManager = new LocalTransactionManager(this.dataSource.getLocalTransaction(getJdbcLogger()));
}
@Override
public DataSource getDataSource() {
return dataSource;
}
@Override
public Dialect getDialect() {
return new MssqlDialect();
}
@Override
public TransactionManager getTransactionManager() {
return transactionManager;
}
}
UserController.java
package jp.masanori.users;
import org.seasar.doma.jdbc.tx.TransactionManager;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import jp.masanori.DomaConfig;
import jp.masanori.users.dao.UserDao;
import jp.masanori.users.models.User;
@Controller("/")
public class UserController {
private final UserDao users;
private final DomaConfig domaConf;
public UserController(UserDao users, DomaConfig domaConf) {
this.users = users;
this.domaConf = domaConf;
}
@Get("/users")
public User findUser() {
TransactionManager tm = domaConf.getTransactionManager();
return tm.required(() -> {
return users.findById(1L);
});
}
}
Top comments (0)