Categories
discuss

Import ES module in Next.js ERR_REQUIRE_ESM

I came upon this error when trying to use ky in a Next.js project:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /foo/node_modules/ky/index.js

I think the problem is that Webpack (or Babel) is transforming all imports to require()s but ky is a pure ES module.

I got it working by dynamically importing ky before using it but it’s not elegant nor efficient.

const handleFormSubmit = async (event) => {
  const ky = (await import("ky")).default;

  const response = await ky
    .get('http://localhost/api/foo')
    .json();
};

Any suggestions?

Answer

From Next.js 12, support for ES Modules is now enabled by default, as long as the ESM library has "type": "module" in its package.json. Using next-transpile-modules to transpile ESM libraries is no longer required.


Before Next.js 12

Since ky is exported as ESM you can transpile it with next-transpile-modules in next.config.js.

// next.config.js
const withTM = require('next-transpile-modules')(['ky']);

module.exports = withTM(/* your Next.js config */);
Categories
discuss

How to cancel with and without interruption using Coroutines on Android, including auto-cancellation according to lifecycle?

Background

I’m having problems in migrating from the simple (deprecated) AsyncTask and Executors to Kotlin Coroutines on Android

The problem

I can’t find how I can perform the basic things I could have done on AsyncTask and even on Executors using Kotlin Coroutines.

In the past, I could choose to cancel a task with and without thread interruption. Now for some reason, given a task that I create on Coroutines, it’s only without interruption, which means that if I run some code that has even “sleep” in it (not always by me), it won’t be interrupted.

I also remember I was told somewhere that Coroutines is very nice on Android, as it automatically cancel all tasks if you are in the Activity. I couldn’t find an explanation of how to do it though.

What I’ve tried and found

For the Coroutines task (called Deferred according to what I see) I think I’ve read that when I create it, I have to choose which cancellation it will support, and that for some reason I can’t have them both. Not sure if this is true, but I still wanted to find out, as I want to have both for best migration. Using AsyncTask, I used to add them to a set (and remove when cancelled) so that upon Activity being finished, I could go over all and cancel them all. I even made a nice class to do it for me.

This is what I’ve created to test this:

class MainActivity : AppCompatActivity() {
    val uiScope = CoroutineScope(Dispatchers.Main)
    val bgDispatcher: CoroutineDispatcher = Dispatchers.IO

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        loadData()
    }

    private fun loadData(): Job = uiScope.launch {
        Log.d("AppLog", "loadData")
        val task = async(bgDispatcher) {
            Log.d("AppLog", "bg start")
            try {
                Thread.sleep(5000L) //this could be any executing of code, including things not editable
            } catch (e: Exception) {
                Log.d("AppLog", "$e")
            }
            Log.d("AppLog", "bg done this.isActive?${this.isActive}")
            return@async 123
        }
        //simulation of cancellation for any reason, sadly without the ability to cancel with interruption
        Handler(mainLooper).postDelayed({
            task.cancel()
        }, 2000L)
        val result: Int = task.await()
        Log.d("AppLog", "got result:$result") // this is called even if you change orientation, which I might not want when done in Activity
    }
}

build gradle file:

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1"

The questions

  1. Is it possible on Coroutines to have a task that I can cancel with and without thread interruption?
  2. What should be added to make this work, so that when the Activity dies (orientation change, for example), it would be auto-cancelled (with the choice of with or without interruption) ? I guess I could use a similar solution as I had for AsyncTask, but I remember I was told there is a nice way to do it for Coroutines too.

Answer

By default, coroutines do not do thread interrupts – as per the Making computation code cancellable documentation, using yield() or checking isActive allows coroutine aware code to participate in cancellation.

However, when interfacing with blocking code where you do want a thread interrupt, this is precisely the use case for runInterruptible(), which will cause the contained code to be thread interrupted when the coroutine scope is cancelled.

This works perfectly with lifecycle-aware coroutine scopes, which automatically cancel when the Lifecycle is destroyed:

class MainActivity : AppCompatActivity() {
    val bgDispatcher: CoroutineDispatcher = Dispatchers.IO

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        loadData()
    }

    private fun loadData(): Job = lifecycleScope.launch {
        Log.d("AppLog", "loadData")
        val result = runInterruptible(bgDispatcher) {
            Log.d("AppLog", "bg start")
            try {
                Thread.sleep(5000L) //this could be any executing of code, including things not editable
            } catch (e: Exception) {
                Log.d("AppLog", "$e")
            }
            Log.d("AppLog", "bg done this.isActive?${this.isActive}")
            return@runInterruptible 123
        }
        Log.d("AppLog", "got result:$result")
    }
}
Categories
discuss

M1 Mac – Issue bringing up ElasticSearch. Cannot run jdk/bin/java

Have done a bit of searching to no avail. Attempting to setup a project with an Elasticsearch docker container. Works on my older intel MacBook but no luck so far with the new system.

elasticsearch    | Exception in thread "main" java.io.IOException: Cannot run program "/usr/share/elasticsearch/jdk/bin/java": error=0, Failed to exec spawn helper.
elasticsearch    |  at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
elasticsearch    |  at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
elasticsearch    |  at org.elasticsearch.tools.launchers.JvmErgonomics.flagsFinal(JvmErgonomics.java:111)
elasticsearch    |  at org.elasticsearch.tools.launchers.JvmErgonomics.finalJvmOptions(JvmErgonomics.java:88)
elasticsearch    |  at org.elasticsearch.tools.launchers.JvmErgonomics.choose(JvmErgonomics.java:59)
elasticsearch    |  at org.elasticsearch.tools.launchers.JvmOptionsParser.main(JvmOptionsParser.java:95)
elasticsearch    | Caused by: java.io.IOException: error=0, Failed to exec spawn helper.
elasticsearch    |  at java.base/java.lang.ProcessImpl.forkAndExec(Native Method)
elasticsearch    |  at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:319)
elasticsearch    |  at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:250)
elasticsearch    |  at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1107)
elasticsearch    |  ... 5 more
elasticsearch exited with code 1

Would greatly appreciate any help or pointing in the right direction!

Answer

Ran into this too with the image from dockerhub, but it seems using the official docker build from Elastic now works fine on my M1 Mac.

docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.10.2
Categories
discuss

API request to Stripe fails (Error: Not a valid URL)

I want to build a simple checkout page using the Stripe Prebuilt Checkout Page in a Node application.

I follow all the necessary steps in the Stripe docs but the API request doesn’t seem to work.

server.js –

const express = require("express");
const stripe = require("stripe")(
  "<mySecretKey>"
);

const app = express();

app.get("/checkout-sucess", (req, res) => {
  res.send("<h1>Success</h1>");
});

app.get("/checkout-cancel", (req, res) => {
  res.send("<h1>Cancelled</h1>");
});

app.post("/create-checkout-session", async (req, res) => {
  const session = await stripe.checkout.sessions.create({
    payment_method_types: ["card"],
    line_items: [
      {
        price_data: {
          currency: "inr",
          product_data: {
            name: "Cewa",
          },
          unit_amount: 200,
        },
        quantity: 1,
      },
    ],
    mode: "payment",
    success_url: "/checkout-success",
    cancel_url: "/checkout-cancel",
  });

  res.json({ id: session.id });
});

app.listen(4242, () => {
  console.log("Server is live on Port 4242!");
});

checkout.html –

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Stripe API Test</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?version=3.52.1&features=fetch"></script>
    <script src="https://js.stripe.com/v3/"></script>
  </head>
  <body>
    <button
      type="button"
      id="checkout-button"
      style="
        padding: 20px;
        background-color: beige;
        cursor: pointer;
        outline: none;
      "
    >
      Checkout
    </button>
  </body>

  <script type="text/javascript">
    var stripe = Stripe(
      "<myPublishableAPIKey"
    );
    var checkoutButton = document.getElementById("checkout-button");
    checkoutButton.addEventListener("click", function () {
      fetch("http://localhost:4242/create-checkout-session", {
        method: "POST",
      })
        .then(function (response) {
          return response.json();
        })
        .then(function (session) {
          return stripe.redirectToCheckout({ sessionId: session.id });
        })
        .then(function (result) {
          // If redirectToCheckout fails due to a browser or network
          // error, you should display the localized error message to your
          // customer using error.message.
          if (result.error) {
            alert(result.error.message);
          }
        })
        .catch(function (error) {
          console.error("Error:", error);
        });
    });
  </script>
</html>

When I make this request, I get the following error in the console coming from checkout.html

Error: Not a valid URL

I don’t think I’ve missed anything from the docs. Any idea what’s going wrong? Thanks in advance.

Answer

You need to add real success and cancel url, please check below code:

const session = await stripe.checkout.sessions.create({
    payment_method_types: ["card"],
    line_items: [
      {
        price_data: {
          currency: "inr",
          product_data: {
            name: "Cewa",
          },
          unit_amount: 200,
        },
        quantity: 1,
      },
    ],
    mode: "payment",
    success_url: "http://sitename.com/checkout-success",
    cancel_url: "http://sitename.com/checkout-cancel",
  });
Categories
discuss

Java final fields: is “taint” behavior possible with the current JLS

I’m currently trying to understand this JLS section on final fields.

To understand the text in the JLS better I’m also reading The Java Memory Model by Jeremy Manson (one of creators of the JMM).

The paper contains the example that got me interested: if an object o with final fields is made visible to another thread t twice:

  • first “improperly” before o‘s constructor finishes
  • next “properly” after o‘s constructor finishes

then t can see semi-constructed o even when it is accessed only via a “properly” published path.

Here is the part from the paper:

Figure 7.3: Example of Simple Final Semantics

f1 is a final field; its default value is 0

Thread 1 Thread 2 Thread 3
o.f1 = 42;
p = o;
freeze o.f1;
q = o;

r1 = p;
i = r1.f1;
r2 = q;
if (r2 == r1)
    k = r2.f1;
r3 = q;
j = r3.f1;



We assume r1, r2 and r3 do not see the value null. i and k can be 0 or 42, and j must be 42.


Consider Figure 7.3. We will not start out with the complications of multiple writes to final fields; a freeze, for the moment, is simply what happens at the end of a constructor. Although r1, r2 and r3 can see the value null, we will not concern ourselves with that; that just leads to a null pointer exception.

What about the read of q.f1 in Thread 2? Is that guaranteed to see the correct value for the final field? A compiler could determine that p and q point to the same object, and therefore reuse the same value for both p.f1 and q.f1 for that thread. We want to allow the compiler to remove redundant reads of final fields wherever possible, so we allow k to see the value 0.

One way to conceptualize this is by thinking of an object being “tainted’ for a thread if that thread reads an incorrectly published reference to the object. If an object is tainted for a thread, the thread is never guaranteed to see the object’s correctly constructed final fields. More generally, if a thread t reads an incorrectly published reference to an object o, thread t forever sees a tainted version of o without any guarantees of seeing the correct value for the final fields of o.

I tried to find in the current JLS anything that explicitly allows or forbids such behavior, but all I found is that:

An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object’s final fields.

Is such behavior allowed in the current JLS?

Answer

Yes, such behavior is allowed.

Turns out that a detailed explanation of this same case is available on the personal page of William Pugh (yet another JMM author): New presentation/description of the semantics of final fields.

Short version:

  • section 17.5.1. Semantics of final Fields of JLS defines special rules for final fields.
    The rules basically lets us establish an additional happens-before relation between the initialization of a final field in a constructor and a read of the field in another thread, even if the object is published via a data race.
    This additional happens-before relation requires that every path from the field initialization to its read in another thread included a special chain of actions:

    w  ʰᵇ ► f  ʰᵇ ► a  ᵐᶜ ► r1  ᵈᶜ ► r2, where:
    • w is a write to the final field in a constructor
    • f is “freeze action”, which happens when constructor exits
    • a is a publication of the object (e.g. saving it to a shared variable)
    • r₁ is a read of the object’s address in a different thread
    • r₂ is a read of the final field in the same thread as r₁.
  • the code in the question has a path from o.f1 = 42 to k = r2.f1; which doesn’t include the required freeze o.f action:

    o.f1 = 42  ʰᵇ ► { freeze o.f is missing }  ʰᵇ ► p = o  ᵐᶜ ► r1 = p  ᵈᶜ ► k = r2.f1

    As a result, o.f1 = 42 and k = r2.f1 are not ordered with happens-before ⇒ we have a data race and k = r2.f1 can read 0 or 42.

A quote from New presentation/description of the semantics of final fields:

In order to determine if a read of a final field is guaranteed to see the initialized value of that field, you must determine that there is no way to construct the partial orders  ᵐᶜ ► and  ᵈᶜ ► without providing the chain w  ʰᵇ f  ʰᵇ a  ᵐᶜ r₁  ᵈᶜ r₂ from the write of the field to the read of that field.

The write in Thread 1 and read in Thread 2 of p are involved in a memory chain. The write in Thread 1 and read in Thread 2 of q are also involved in a memory chain. Both reads of f see the same variable. There can be a dereference chain from the reads of f to either the read of p or the read of q, because those reads see the same address. If the dereference chain is from the read of p, then there is no guarantee that r5 will see the value 42.

Notice that for Thread 2, the deference chain orders r2 = p  ᵈᶜ r5 = r4.f, but does not order r4 = q  ᵈᶜ r5 = r4.f. This reflects the fact that the compiler is allowed to move any read of a final field of an object o to immediately after the the very first read of the address of o within that thread.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..