Thread safety error; this instance of WebDriver was constructed on thread Test worker (id 1) and is being accessed by thread awaitility-thread (id 92)This is not permitted and *will* cause undefined behaviour
Build info: version: '4.6.0', revision: '79f1c02ae20'
System info: os.name: 'Mac OS X', os.arch: 'aarch64', os.version: '12.6', java.version: '17.0.2'
Driver info: driver.version: unknown
org.openqa.selenium.WebDriverException: Thread safety error; this instance of WebDriver was constructed on thread Test worker (id 1) and is being accessed by thread awaitility-thread (id 92)This is not permitted and *will* cause undefined behaviour
Build info: version: '4.6.0', revision: '79f1c02ae20'
System info: os.name: 'Mac OS X', os.arch: 'aarch64', os.version: '12.6', java.version: '17.0.2'
Driver info: driver.version: unknown
at app//org.openqa.selenium.support.ThreadGuard$WebDriverInvocationHandler.invoke(ThreadGuard.java:88)
at app/jdk.proxy3/jdk.proxy3.$Proxy28.getCurrentUrl(Unknown Source)
at app//InputCheckedTest.checkBeforeAndAfterClick$lambda$0(MyTest.kt:55)
at app//org.awaitility.core.AssertionCondition.lambda$new$0(AssertionCondition.java:53)
at app//org.awaitility.core.ConditionAwaiter$ConditionPoller.call(ConditionAwaiter.java:248)
at app//org.awaitility.core.ConditionAwaiter$ConditionPoller.call(ConditionAwaiter.java:235)
at java.base@17.0.2/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base@17.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base@17.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base@17.0.2/java.lang.Thread.run(Thread.java:833)
2022-11-12 09:15:39.580 [Test worker] INFO kweb.Kweb - Shutting down Kweb
2022-11-12 09:15:39.586 [Test worker] INFO o.e.jetty.server.AbstractConnector - Stopped ServerConnector@4f824872{HTTP/1.1, (http/1.1, h2c)}{0.0.0.0:7660}
InputCheckedTest > checkBeforeAndAfterClick() FAILED
But in my opinion, it's bit complex and tricky way.
In my opinion, spring-boot users want to use the spring-boot's configuration loading feature and the bean management feature. But the sample code demonstrates the kweb integration with the spring-webmvc's servlet container.
This code demonstrates, the code starts kweb server and it runs with spring-boot's beans and configurations. While the shutdown process, spring will call the "close" method on the Kweb instance!
として cert-manager を入れる(digital ocean の web ui からも入れられるけど)
以下のようにして cert-manager を管理する。これも kubectl apply -f すれば OK
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# Email address used for ACME registration
email: tokuhirom@gmail.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Name of a secret used to store the ACME account private key
name: letsencrypt-prod-private-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s qq q and s s s chr length q q each die local chown rmdir tie chr q semop and s s s chr length q qr our xor getc dump order goto log join eof write time crypt dump exit vec index open ord tied q semop and s s s chr length q q each die local chown rmdir tie chr dump fcntl warn ord eval q semop and s s s chr length q qr our break chop given given pack q semop and s s s chr length q qr our break chop given given pack q semop and s s s chr length q qr our break chop given given pack exit ord goto read undef q semop and s s s chr length q qr our break chop given given pack exit ord goto read undef exp recv tell xor wait exit tell time bind tell each given q semop and s s s length q qr our break chop given given pack exit ord goto read undef exp recv tell xor wait exit tell time bind tell our log q semop and s s s chr length q qr our xor untie chomp lock chdir vec cmp pipe q semop and s s s length q qr our break chop given given pack exit ord goto read undef exp recv tell xor wait exit tell time q semop and s s s chr length q qr our xor untie chomp lock chdir vec cmp pipe q semop and s s s length q q each die local chown rmdir tie flock hex alarm undef cmp each ord glob ioctl untie die chr untie pack exp cmp given ref q semop and s s s chr length q qr our xor untie chomp lock chdir vec cmp pipe q semop and s s s length q q each die local chown rmdir tie q semop and s s s chr length q qr our xor untie chomp lock chdir vec cmp pipe q semop and s s s length q qr our break chop given given pack q semop and s s s chr length q qr our xor untie chomp lock chdir vec cmp pipe q semop and s s s length q q each die local chown rmdir tie flock hex alarm undef cmp each ord glob q semop and s s s chr length q qr our xor untie chomp lock chdir vec cmp pipe q semop and s s s length q q each die local chown rmdir tie flock hex alarm undef cmp each ord glob ioctl untie die chr link tie q semop and s s s chr length q qr our xor untie chomp lock chdir vec cmp pipe q semop and s s s length q qr our break chop given given pack exit ord goto read undef exp recv tell xor wait exit tell time bind fcntl q semop and s s s chr length q qr our xor untie chomp lock chdir vec cmp pipe q semop and s s s length q qr our break chop given given pack exit ord goto read undef exp recv tell xor wait exit tell time bind fcntl q semop and s s s chr length q qr our xor untie chomp lock chdir vec cmp pipe q semop and s s s length q q each die local chown rmdir tie flock hex alarm undef cmp each ord glob ioctl untie die chr untie pack exp cmp q semop and s s s chr length q qr our xor untie chomp lock chdir vec cmp pipe q semop and s s s length q qr our break chop given given pack q semop and eval eval
RUN cpanm Amon2
RUN cpanm DBD::SQLite LWP::Protocol::https DBD::mysql
RUN cpanm Catalyst::Runtime
RUN cpanm DBIx::Class
RUN cpanm Dist::Milla
RUN cpanm Tiffany
RUN cpanm Task::BeLike::TOKUHIROM
RUN cpanm Test::Perl::Critic Perl::Critic
RUN cpanm HTTP::Server::Simple::CGI Spiffy WWW::MobileCarrierJP
@file:DependsOn("org.jodd:jodd-http:6.2.1")
@file:DependsOn("org.jodd:jodd-lagarto:6.0.6")
import jodd.http.HttpRequest
import jodd.jerry.Jerry
data class Comment(
val id: String,
val user: String,
val time: String,
val comment: String,
val parent: String?,
)
var url = args[0]
val commentList = mutableListOf<Comment>()
while (true) {
println("Scraping $url")
// Send the HTTP request to our URL
val response = HttpRequest.get(url).send()
// Parse the HTML document into a Jerry DOM object
val doc = Jerry.of(response.bodyText())
// Find all comments <tr>s in the main comment table
val comments = doc.find("table.comment-tree tr.comtr")
// Iterate over each comment and extract its data
comments.forEach { element ->
val id = element.attr("id")
val user = element.find("a.hnuser").text()
val time = element.find("span.age").attr("title")
val comment = element.find("div.comment").text()
val parent = element.find("a:contains(parent)").attr("href")
// Append the data to comment_list
commentList.add(Comment(id, user, time, comment, parent))
}
// If there is a next link, set the URL and continue the while, otherwise exit
val next = doc.find("""a[rel="next"]""").attr("href")
if (next != null) url = "https://news.ycombinator.com/$next"
else break
}
println(commentList)
配布用パッケージの作成
kscript --package scraping.kts
とすると、java コマンドさえあれば実行できるバイナリを生成可能。このバイナリは mac でも linux でも動く。windows なら WSL の上でなら動くはず。
#!/usr/bin/env kscript
@file:DependsOn("com.offbytwo:docopt:0.6.0.20150202", "log4j:log4j:1.2.14")
import org.docopt.Docopt
import java.util.*
val usage = """
Use this cool tool to do cool stuff
Usage: cooltool.kts [options] <igenome> <fastq_files>...
Options:
--gtf <gtfFile> Custom gtf file instead of igenome bundled copy
--pc-only Use protein coding genes only for mapping and quantification
"""
val doArgs = Docopt(usage).parse(args.toList())
println("Hello from Kotlin!")
println("Parsed script arguments are: \n" + doArgs)
@file:DependsOn("com.github.holgerbrandl:kscript-support-api:1.2.5")
import kscript.text.*
val lines = resolveArgFile(args)
外部コマンドの実行
kutils を使うとかんたんに外部コマンドを実行できる。便利。
@file:DependsOn("com.github.holgerbrandl:kutils:0.12")
import de.mpicbg.scicomp.kutils.evalBash
val result = evalBash("date")
println(result.exitCode)
println(result.sout())