I am trying to run OpenBLAS preset in the DL4J library but i am having a problem in SetNumThreads.allocate()
the library implementation in build.gradle:
implementation group: 'org.bytedeco.javacpp-presets', name: 'openblas', version: '0.3.3-1.4.3', classifier: "android-arm"
implementation group: 'org.bytedeco.javacpp-presets', name: 'openblas', version: '0.3.3-1.4.3', classifier: "android-arm64"
implementation group: 'org.bytedeco.javacpp-presets', name: 'openblas', version: '0.3.3-1.4.3', classifier: "android-x86"
implementation group: 'org.bytedeco.javacpp-presets', name: 'openblas', version: '0.3.3-1.4.3', classifier: "android-x86_64"
and multiDexEnabled true.
When i run this method in my android app:
INDArray i = Nd4j.zeros(height, width, channels);
I get this error message:
Caused by: java.lang.UnsatisfiedLinkError: No implementation found for void org.bytedeco.openblas.presets.openblas_nolapack$SetNumThreads.allocate()
(tried Java_org_bytedeco_openblas_presets_openblas_1nolapack_00024SetNumThreads_allocate and Java_org_bytedeco_openblas_presets_openblas_1nolapack_00024SetNumThreads_allocate__)
Related
OpenJDK 11
Provider com.sun.xml.internal.ws.spi.ProviderImpl not found(javax.xml.ws)
I get this exception when I use soap WS Services
gradle 7.5, javax, jakarta dependencies:
api group: 'jakarta.ws.rs', name: 'jakarta.ws.rs-api', version: '2.1.6'
api group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '2.3.3' //3.0.0 did not work!
api group: 'jakarta.xml.ws', name: 'jakarta.xml.ws-api', version: '2.3.3'
api group: 'jakarta.jws', name: 'jakarta.jws-api', version: '2.1.0'
api group: 'jakarta.jws', name: 'jakarta.jws-api', version: '2.1.0'
api group: 'jakarta.xml.soap', name: 'jakarta.xml.soap-api', version: '1.4.2'
api group: 'com.sun.xml.bind', name: 'jaxb-core', version: '2.3.0'
api group: 'com.sun.xml.bind', name: 'jaxb-impl', version: '2.3.0'
I am using selenium "4.1.2" with chrome 97. While selecting value from drop down using select class, getting exception:
java.lang.NoSuchMethodError: org.openqa.selenium.WebElement.getDomAttribute(Ljava/lang/String;)Ljava/lang/String;
Below are dependencies in my project:
ext {
selenium = '4.1.2'
webdrivermanager = '5.0.3'
}
dependencies {
compile("org.seleniumhq.selenium:selenium-java:${selenium}")
// compile("io.github.bonigarcia:webdrivermanager:${webdrivermanager}")
testImplementation "org.seleniumhq.selenium:selenium-chrome-driver:${selenium}"
testImplementation "org.seleniumhq.selenium:selenium-firefox-driver:${selenium}"
testImplementation "org.seleniumhq.selenium:selenium-ie-driver:${selenium}"
testImplementation "org.seleniumhq.selenium:selenium-edge-driver:${selenium}"
testImplementation "org.seleniumhq.selenium:selenium-safari-driver:${selenium}"
testImplementation "org.seleniumhq.selenium:selenium-remote-driver:${selenium}"
testImplementation "org.seleniumhq.selenium:selenium-support:${selenium}"
testImplementation('org.junit.jupiter:junit-jupiter:5.5.1')
testImplementation 'org.hamcrest:hamcrest:2.1'
testImplementation 'org.hamcrest:hamcrest-library:2.1'
testCompile("org.junit.jupiter:junit-jupiter-api:5.7.2")
testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.7.2'
testRuntime("org.junit.platform:junit-platform-launcher:1.7.2")
testCompile('io.github.bonigarcia:selenium-jupiter:3.3.4')
compile group: 'io.qameta.allure', name: 'allure-junit5', version: '2.11.0'
compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.16'
implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.17.1'
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.17.1'
compile group: 'io.qameta.allure', name: 'allure-gradle', version: '2.7.0'
compile 'org.apache.maven.plugins:maven-surefire-plugin:2.21.0'
compile('com.assertthat:selenium-shutterbug:1.5')
compile 'org.slf4j:slf4j-nop:1.7.25'
implementation group: 'javax.mail', name: 'mail', version: '1.4.7'
implementation group: 'javax.mail', name: 'javax.mail-api', version: '1.6.2'
runtimeClasspath group: 'javax.mail', name: 'javax.mail-api', version: '1.6.2'
compile group: 'net.lightbody.bmp', name: 'browsermob-core', version: '2.1.4'
compile group: 'org.postgresql', name: 'postgresql', version: '42.2.14'
compile group: 'org.mongodb', name: 'mongo-java-driver', version: '3.12.4'
compile group: 'ru.yandex.qatools.ashot', name: 'ashot', version: '1.5.4'
implementation group: 'org.json', name: 'json', version: '20201115'
implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
testImplementation group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.7.2'
testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: '1.7.2'
testImplementation group: 'org.junit.platform', name: 'junit-platform-surefire-provider', version: '1.3.2'
}
Any help in resolving this issue is highly appreciated.
This error message...
java.lang.NoSuchMethodError: org.openqa.selenium.WebElement.getDomAttribute(Ljava/lang/String;)Ljava/lang/String;
...is the result of dependency version conflict.
Deep Dive
As per #titusfortner comment in the discussion you need to crosscheck that everything related to Selenium is set to 4.x and that nothing that requires Selenium 3.x (e.g., Appium 7) is included in your dependencies as #asolntsev in the comment mentions:
All implementations of WebElement do override method getDomAttribute(). It never throws UnsupportedOperationException in real life.
Solution
You need to execute mvn dependency:tree or gradle dependencies and you will be able to trace the problem as described in this example.
I would try forcing below dependency in build.gradle
implementation (group: 'org.seleniumhq.selenium', name: 'selenium-api', version: '4.1.2') { force = true }
NoSuchMethod error occurs when dependency version conflict happens. If you are using lower version Appium, upgrading to following version,
implementation 'io.appium:java-client:8.0.0'
may resolve errors.
I have some Android code that needs to find contours and outline them with rectangles. I have no problems with OpenCV initialization (all other functions work fine). But when I run Imgproc.boundingRect(contours.get(i)); error java.lang.NoSuchMethodError occurs.
2021-09-03 18:24:24.331 23081-23081/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.fern.mangoeye, PID: 23081
java.lang.NoSuchMethodError: No static method boundingRect(Lorg/opencv/core/Mat;)Lorg/opencv/core/Rect; in class Lorg/opencv/imgproc/Imgproc; or its super classes (declaration of 'org.opencv.imgproc.Imgproc' appears in /data/app/com.fern.mangoeye-jmLx1kABmB7GFFie5xaCyA==/base.apk!classes9.dex)
at com.fern.mangoeye.OpenCVHandler.feedNewYUVData(OpenCVHandler.java:132)
at com.fern.mangoeye.CameraView.onPreviewFrame(CameraView.java:140)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1221)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
OpenCV initialization has OpenCVLoader.initDebug() as well as BaseLoaderCallback
OpenCV SDK version: 3.4.1
compileSdk: 31
I solved my problem by specifying exclude group: 'org.bytedeco', module: 'opencv' for implementation (group: 'org.bytedeco', name: 'javacv', version: '1.5.5') in build.gradle.
So now my dependencies looks like this:
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation project(path: ':opencv')
implementation 'org.jcodec:jcodec:0.2.5'
implementation (group: 'org.bytedeco', name: 'javacv', version: '1.5.5'){
exclude group: 'org.bytedeco', module: 'opencv'
}
implementation group: 'org.bytedeco', name: 'openblas', version: '0.3.13-1.5.5', classifier: 'android-arm'
implementation group: 'org.bytedeco', name: 'openblas', version: '0.3.13-1.5.5', classifier: 'android-arm64'
implementation group: 'org.bytedeco', name: 'openblas', version: '0.3.13-1.5.5', classifier: 'android-x86_64'
implementation group: 'org.bytedeco', name: 'openblas', version: '0.3.13-1.5.5', classifier: 'android-x86'
implementation group: 'org.bytedeco', name: 'ffmpeg', version: '4.3.2-1.5.5', classifier: 'android-arm'
implementation group: 'org.bytedeco', name: 'ffmpeg', version: '4.3.2-1.5.5', classifier: 'android-arm64'
implementation group: 'org.bytedeco', name: 'ffmpeg', version: '4.3.2-1.5.5', classifier: 'android-x86_64'
implementation group: 'org.bytedeco', name: 'ffmpeg', version: '4.3.2-1.5.5', classifier: 'android-x86'
}
Also I created jni folder and copy folders from sdk\native\libs to it. So, the problem was with the initialization of OpenCV
I m currently trying to write a Publisher for Kafka Messages using Spark and Java. The requirement is I will have a Dataset with few records. I need to only publish these records on Kafka queue on a topic.
Following is the publisher code written in Java:
Dataset dataset = messageDataSet.select("value");
dataset.selectExpr("CAST(value AS STRING)")
.write()
.format("kafka")
.option("topic","batch")
.option("kafka.bootstrap.servers","kafka01.qa.com:9092")
.save();
I have added following things is gradle , since the deployment guide of Streaming Kafka Integration says to have the gradle dependecies as provided I have also tried that.
dependencies {
compile group: 'com.util', name:'core-utilities-jdk8',version: '0.0.2-spark'
compile group: 'org.postgresql', name: 'postgresql', version: '42.2.8'
compile group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.687'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
compile group: 'org.apache.spark', name: 'spark-core_2.12', version: "$sparkVersion"
compile group: 'org.apache.spark', name: 'spark-sql_2.12', version: "$sparkVersion"
compile group: 'com.databricks', name: 'spark-csv_2.11', version: '1.5.0'
compile group: 'commons-logging', name: 'commons-logging', version: '1.2'
compile group: 'org.apache.spark', name: 'spark-streaming-kafka-0-10_2.11', version: "$sparkVersion"
compile group: 'org.apache.spark', name: 'spark-streaming_2.12', version: "$sparkVersion"
compile group: 'org.apache.spark', name: 'spark-sql-kafka-0-10_2.12', version: "$sparkVersion"
annotationProcessor 'org.projectlombok:lombok:1.18.10'
compile group: 'org.projectlombok', name: 'lombok', version: '1.18.10'
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
compile 'org.apache.httpcomponents:httpmime:4.3.6'
compile group: 'org.apache.commons', name: 'commons-csv', version: '1.7'
compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-scala_2.12', version: '2.10.1'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.10.1'
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.10.1'
compile group: 'com.jcraft', name: 'jsch', version: '0.1.55'
}
The dependecy I have tried as ProvidedCompile for Kafka and Spark Core but the error continues to be following :
User class threw exception: java.util.ServiceConfigurationError:
org.apache.spark.sql.sources.DataSourceRegister: Provider
org.apache.spark.sql.kafka010.KafkaSourceProvider could not be instantiated
at java.util.ServiceLoader.fail(ServiceLoader.java:232)
at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
at scala.collection.convert.Wrappers$JIteratorWrapper.next(Wrappers.scala:43)
at scala.collection.Iterator$class.foreach(Iterator.scala:891)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1334)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at scala.collection.TraversableLike$class.filterImpl(TraversableLike.scala:247)
at scala.collection.TraversableLike$class.filter(TraversableLike.scala:259)
at scala.collection.AbstractTraversable.filter(Traversable.scala:104)
at org.apache.spark.sql.execution.datasources.DataSource$.lookupDataSource(DataSource.scala:630)
at org.apache.spark.sql.DataFrameWriter.save(DataFrameWriter.scala:245)
at com.fileprocessor.jobs.Runner.publishMessage(Runner.java:200)
at com.fileprocessor.SparkFileProcessorMain.main(SparkFileProcessorMain.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.spark.deploy.yarn.ApplicationMaster$$anon$2.run(ApplicationMaster.scala:684)
Caused by: java.lang.NoSuchMethodError:
org.apache.spark.internal.Logging.$init$(Lorg/apache/spark/internal/Logging;)V
at org.apache.spark.sql.kafka010.KafkaSourceProvider.<init>(KafkaSourceProvider.scala:44)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
I want to simply publish by dataset to Kafka Queues . Spark version is 2.4.4
I have went through the different results of Having transformenrs in Gradle , or downgrading the things for Kafka versions and scala . But nothing has helped . Anyone if have faced similar situation ?
Tried : spark-submit --packages org.apache.spark:spark-sql-kafka-0-10_2.11:2.4.4 --class com.fileprocessor.SparkFileProcessorMain --master local[*] file-processor-spark-jobs-1.0-SNAPSHOT.jar
Or If any one have anyother way to write the similar code ?
Following gradle worked:
dependencies {
compile group: 'org.postgresql', name: 'postgresql', version: '42.2.8'
compile group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.687'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
compile group: 'org.apache.spark', name: 'spark-core_2.12', version: "$sparkVersion"
compile group: 'org.apache.spark', name: 'spark-sql_2.12', version: "$sparkVersion"
compile group: 'com.databricks', name: 'spark-csv_2.11', version: '1.5.0'
compile group: 'commons-logging', name: 'commons-logging', version: '1.2'
compile group: 'org.apache.spark', name: 'spark-streaming-kafka-0-10_2.11', version: "$sparkVersion"
providedCompile group: 'org.apache.spark', name: 'spark-streaming_2.12', version: "$sparkVersion"
providedCompile group: 'org.apache.spark', name: 'spark-sql-kafka-0-10_2.11', version: "2.2.0"
annotationProcessor 'org.projectlombok:lombok:1.18.10'
compile group: 'org.projectlombok', name: 'lombok', version: '1.18.10'
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
compile 'org.apache.httpcomponents:httpmime:4.3.6'
compile group: 'org.apache.commons', name: 'commons-csv', version: '1.7'
compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-scala_2.12', version: '2.10.1'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.10.1'
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.10.1'
compile group: 'com.jcraft', name: 'jsch', version: '0.1.55'
}
And spark submit : spark-submit --packages org.apache.spark:spark-sql-kafka-0-10_2.11:2.3.0 --class com.fileprocessor.SparkFileProcessorMain --master local[*] file-processor-spark-jobs-1.0-SNAPSHOT.jar test bottomline false
I try to run project with gretty. It throws exception:
10:47:39 WARN Failed startup of context o.a.g.JettyWebAppContext#52045dbe{/,file:/C:/IdeaProjects/example-tab/build/inplaceWebapp/,STARTING}
java.lang.RuntimeException: Error scanning entry module-info.class from jar file:/C:/Users/user1/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-api/2.10.0/fec5797a55b786184a537abd39c3fa1449d752d6/log4j-api-2.10.0.jar
at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:913) ~[jetty-annotations-9.2.24.v20180105.jar:9.2.24.v20180105]
at org.eclipse.jetty.annotations.AnnotationParser.parse(AnnotationParser.java:831) ~[jetty-annotations-9.2.24.v20180105.jar:9.2.24.v20180105]
at org.eclipse.jetty.annotations.AnnotationConfiguration$ParserTask.call(AnnotationConfiguration.java:164) ~[jetty-annotations-9.2.24.v20180105.jar:9.2.24.v20180105]
at org.eclipse.jetty.annotations.AnnotationConfiguration$1.run(AnnotationConfiguration.java:549) ~[jetty-annotations-9.2.24.v20180105.jar:9.2.24.v20180105]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) ~[jetty-util-9.2.24.v20180105.jar:9.2.24.v20180105]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) ~[jetty-util-9.2.24.v20180105.jar:9.2.24.v20180105]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_171]
Caused by: java.lang.UnsupportedOperationException: null
at org.objectweb.asm.ClassVisitor.visitModule(ClassVisitor.java:129) ~[asm-6.1.1.jar:na]
at org.objectweb.asm.ClassReader.readModule(ClassReader.java:667) ~[asm-6.1.1.jar:na]
at org.objectweb.asm.ClassReader.accept(ClassReader.java:503) ~[asm-6.1.1.jar:na]
at org.objectweb.asm.ClassReader.accept(ClassReader.java:355) ~[asm-6.1.1.jar:na]
at org.eclipse.jetty.annotations.AnnotationParser.scanClass(AnnotationParser.java:974) ~[jetty-annotations-9.2.24.v20180105.jar:9.2.24.v20180105]
at org.eclipse.jetty.annotations.AnnotationParser.parseJarEntry(AnnotationParser.java:956) ~[jetty-annotations-9.2.24.v20180105.jar:9.2.24.v20180105]
at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:909) ~[jetty-annotations-9.2.24.v20180105.jar:9.2.24.v20180105]
... 6 common frames omitted
gradle:
plugins {
id 'java'
id 'war'
id "org.gretty" version "2.2.0"
}
group 'ru.example'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
compileJava.options.encoding = 'UTF-8'
ext {
SPRING_VERSION = '5.1.0.RELEASE'
JUNIT_VERSION = '5.3.1'
JACKSON_VERSION = '2.9.7'
}
repositories {
mavenCentral()
jcenter()
maven {
url 'https://oss.sonatype.org/content/repositories/releases/'
}
}
gretty {
springBootVersion = '2.0.5.RELEASE'
contextPath = "/"
}
dependencies {
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.2'
compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.2'
compileOnly group: 'com.google.appengine', name: 'appengine-endpoints-deps', version: '1.9.65'
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
compile group: 'org.springframework', name: 'spring-webmvc', version: SPRING_VERSION
compile group: 'org.springframework', name: 'spring-web', version: SPRING_VERSION
compile group: 'org.springframework', name: 'spring-jdbc', version: SPRING_VERSION
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.0.5.RELEASE'
compile group: 'com.mchange', name: 'c3p0', version: '0.9.5.2'
compile group: 'com.zaxxer', name: 'HikariCP', version: '3.2.0'
compile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.3.0'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: JACKSON_VERSION
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: JACKSON_VERSION
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.7'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: JUNIT_VERSION
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: JUNIT_VERSION
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.3.1'
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.22.0'
testCompile group: 'org.springframework', name: 'spring-test', version: SPRING_VERSION
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3'
testCompile group: 'com.jayway.jsonpath', name: 'json-path-assert', version: '2.4.0'
}
test {
useJUnitPlatform()
}
Scanning internet not helped. Please advice how to run it correctly. I had problems with downloading dependencies from jcenter(), may be, problem is here.
Validator write that my question have mostly code, but I have no Idea what to add to my explain, than, my apologies, I'll quote Steve Jobs:
“You can’t connect the dots looking forward; you can only connect them looking backward. So you have to trust that the dots will somehow connect in your future.”
You introduced a JEP-238 Jar file into your project: log4j-api-2.10.0.jar
Support for JEP-238 Jar files on any Java Runtime (doesn't matter if it's Java 7, Java 8, Java 9, Java 10, Java 11, or even the new Java 12-ea releases) was first introduced in Jetty 9.4.9.
You have 2 options:
Don't use JEP-238 Jar Files in your project.
Upgrade to Jetty 9.4.9 (or newer) to have support for JEP-238 Jar Files.
See past answers:
https://stackoverflow.com/a/45362629/775715
https://stackoverflow.com/a/52722120/775715