问:
Is it possible to prevent browser from loading Service Worker file on each IFrame navigation request?
I have a single page application which switches content in an IFrame regularly. This app should be able to work offline and it's using a simple generated service worker using workbox CLI.

All content comes from the same origin and offline caching works fine.

But each time the IFrame src changes the browser engine (checked with Firefox 108 and Chromium 108) fetches the sw.js file when online.

Does exist any way to prevent this?

Background: the app is running on IoT devices connected over mobile network, so traffic matters. With a moderate complex service worker about 75 KB Code and 4 requests per minute this can easily consume about 400 MB per day per device, which is quite expensive when using mobile network.

To be sure that the problem is not specific to my (somewhat complex) application I build some minimalistic proof of concept code, with just a simple index.html, main.js and iframe content files and generated the service worker with workbox generateSW.

The webserver log shows that on every IFrame change the sw.js file is fully requested from the browser engine with status 200 (and not 304 which would be probably OK).

dist/index.html

<!DOCTYPE html>

    <title>SW IFrame PoC</title>

SW Iframe PoC

```
<p><strong>dist/main.js</strong></p>
<pre class="lang-js prettyprint-override"><code>(function () {
  const frame = document.getElementById("frame");

  function changeIframe(src) {
    const iFrame = document.getElementById("nav-iframe");
    if (!iFrame) {
      frame.innerHTML = `<iframe id="nav-iframe" src="${src}" style="width:500px;height:500px"></iframe>`;
    } else {
      iFrame.src = src;
    }
  }

  function setupIframeSwitcher() {
    changeIframe("iframe1.html");
    setInterval(() => {
      changeIframe("iframe1.html");
    }, 6000);
    setTimeout(() => {
      changeIframe("iframe2.html");
      setInterval(() => {
        changeIframe("iframe2.html");
      }, 6000);
    }, 3000);
  }

  setupIframeSwitcher();
})();
</code>```

dist/iframe1.html (and very similar is dist/iframe2.html)

<!DOCTYPE html>

    <title>SW IFrame #1</title>

SW IFrame #1

```
<p><strong>workbox-config.js</strong></p>
<pre class="lang-js prettyprint-override"><code>module.exports = {
  globDirectory: "dist/",
  globPatterns: ["**/*.{html,js}"],
  swDest: "dist/sw.js",
};
</code>```

package.json

{
  "name": "sw-iframe",
  "version": "0.1.0",
  "description": "SW IFrame PoC",
  "license": "MIT",
  "devDependencies": {
    "http-server": "^14.1.1",
    "workbox-cli": "^6.5.4"
  },
  "scripts": {
    "build": "workbox generate",
    "start": "http-server -p 8000 dist"
  }
}
```
<p>The output from "yarn start" shows a hit on "/sw.js" every 3s (unfortunately the http-server module does not report the status 200 here, but I checked that in my Apache logs):</p>
```...
[2023-01-04T08:31:42.558Z]  "GET /sw.js" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0"
[2023-01-04T08:31:45.557Z]  "GET /sw.js" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0"
[2023-01-04T08:31:48.553Z]  "GET /sw.js" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0"
[2023-01-04T08:31:51.549Z]  "GET /sw.js" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0"
...
```

Body:
I have a single page application which switches content in an IFrame regularly. This app should be able to work offline and it's using a simple generated service worker using workbox CLI.

All content comes from the same origin and offline caching works fine.

But each time the IFrame src changes the browser engine (checked with Firefox 108 and Chromium 108) fetches the sw.js file when online.

Does exist any way to prevent this?

Background: the app is running on IoT devices connected over mobile network, so traffic matters. With a moderate complex service worker about 75 KB Code and 4 requests per minute this can easily consume about 400 MB per day per device, which is quite expensive when using mobile network.

To be sure that the problem is not specific to my (somewhat complex) application I build some minimalistic proof of concept code, with just a simple index.html, main.js and iframe content files and generated the service worker with workbox generateSW.

The webserver log shows that on every IFrame change the sw.js file is fully requested from the browser engine with status 200 (and not 304 which would be probably OK).

dist/index.html

<!DOCTYPE html>

    <title>SW IFrame PoC</title>

SW Iframe PoC

dist/main.js

(function () {
  const frame = document.getElementById("frame");

  function changeIframe(src) {
    const iFrame = document.getElementById("nav-iframe");
    if (!iFrame) {
      frame.innerHTML = `<iframe id="nav-iframe" src="${src}" style="width:500px;height:500px"></iframe>`;
    } else {
      iFrame.src = src;
    }
  }

  function setupIframeSwitcher() {
    changeIframe("iframe1.html");
    setInterval(() => {
      changeIframe("iframe1.html");
    }, 6000);
    setTimeout(() => {
      changeIframe("iframe2.html");
      setInterval(() => {
        changeIframe("iframe2.html");
      }, 6000);
    }, 3000);
  }

  setupIframeSwitcher();
})();

dist/iframe1.html (and very similar is dist/iframe2.html)

<!DOCTYPE html>

    <title>SW IFrame #1</title>

SW IFrame #1

workbox-config.js

module.exports = {
  globDirectory: "dist/",
  globPatterns: ["**/*.{html,js}"],
  swDest: "dist/sw.js",
};

package.json

{
  "name": "sw-iframe",
  "version": "0.1.0",
  "description": "SW IFrame PoC",
  "license": "MIT",
  "devDependencies": {
    "http-server": "^14.1.1",
    "workbox-cli": "^6.5.4"
  },
  "scripts": {
    "build": "workbox generate",
    "start": "http-server -p 8000 dist"
  }
}

The output from "yarn start" shows a hit on "/sw.js" every 3s (unfortunately the http-server module does not report the status 200 here, but I checked that in my Apache logs):

...
[2023-01-04T08:31:42.558Z]  "GET /sw.js" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0"
[2023-01-04T08:31:45.557Z]  "GET /sw.js" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0"
[2023-01-04T08:31:48.553Z]  "GET /sw.js" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0"
[2023-01-04T08:31:51.549Z]  "GET /sw.js" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0"
...


来源: stackexchange

问:
How to process continues real time data of received by zmq receiver in python dataframe?
I am collecting/receiving data of received signal continuously in real time and receiving through the zmq pull and then saving it in csv format. The received data is in numeric values of presence of peak signal. whenever i got peak there is peak value otherwise value is zero.

Now this data is coming in sets. i want to save this data in csv continuousy in column row by row and after 70k sample data, the data will move to next column and so on.

```<code>import pandas as pd
import time
import zmq
import random
import numpy as np
import matplotlib.pyplot as plt
import csv
coldata = []
def consumer():
    context = zmq.Context()
    consumer_receiver = context.socket(zmq.PULL)
    consumer_receiver.connect("tcp://127.0.0.1:5557")

    while True:
        buff = consumer_receiver.recv()
        received_data = np.frombuffer(buff, dtype="float32", count=-1, offset=0)
        realdata = pd.DataFrame([received_data])
        coldata = realdata.T
        print(len(data))
        for i in range(5):
            coldata.loc[i] = list(data(size=70000))
        coldata.to_csv("dataframed samples008.csv", mode ='a')
        print(coldata)

## here i was trying to wite and then by reading trying to manipulate
## but i'm very new to pandas and dont know how to do it

        with open("csv00030.csv","a",newline='') as f:
                  sample_data = csv.writer(f)
                  sample_data.writerow(data)
        with open("csv00030.csv","r",newline='') as file:
            csvFile = csv.reader(file)
            for samples in csvFile:
                      print(samples)

# write 70k samples data in each row or column
#

consumer()

</code>```

ContentLicense: CC BY-SA 4.0

Body:
I am collecting/receiving data of received signal continuously in real time and receiving through the zmq pull and then saving it in csv format. The received data is in numeric values of presence of peak signal. whenever i got peak there is peak value otherwise value is zero.

Now this data is coming in sets. i want to save this data in csv continuousy in column row by row and after 70k sample data, the data will move to next column and so on.

import pandas as pd
import time
import zmq
import random
import numpy as np
import matplotlib.pyplot as plt
import csv
coldata = []
def consumer():
    context = zmq.Context()
    consumer_receiver = context.socket(zmq.PULL)
    consumer_receiver.connect("tcp://127.0.0.1:5557")

    while True:
        buff = consumer_receiver.recv()
        received_data = np.frombuffer(buff, dtype="float32", count=-1, offset=0)
        realdata = pd.DataFrame([received_data])
        coldata = realdata.T
        print(len(data))
        for i in range(5):
            coldata.loc[i] = list(data(size=70000))
        coldata.to_csv("dataframed samples008.csv", mode ='a')
        print(coldata)

## here i was trying to wite and then by reading trying to manipulate
## but i'm very new to pandas and dont know how to do it

        with open("csv00030.csv","a",newline='') as f:
                  sample_data = csv.writer(f)
                  sample_data.writerow(data)
        with open("csv00030.csv","r",newline='') as file:
            csvFile = csv.reader(file)
            for samples in csvFile:
                      print(samples)

# write 70k samples data in each row or column
#

consumer()


问:
Window.open() opens raw text instead of actual file
In Angular app when I try to open a blob file received from the api using the following method in Chrome or Edge browser, a new tab opens with raw text instead of the corresponding file.

```<code>  static openFileInTab = (blob: Blob) => {
    const url = URL.createObjectURL(blob);
    window.open(url, '_blank');
  };
</code>```

or

```<code>  static openFileInTab = (blob: Blob) => {
    const url = URL.createObjectURL(blob);
    const anchor = document.createElement('a');
    anchor.href = url;
    anchor.target = '_blank';
    anchor.click();
  };
</code>```

In Firefox both of the following methods work correctly, but not in Chrome/Edge.

How do I solve this problem?

Body:
In Angular app when I try to open a blob file received from the api using the following method in Chrome or Edge browser, a new tab opens with raw text instead of the corresponding file.

  static openFileInTab = (blob: Blob) => {
    const url = URL.createObjectURL(blob);
    window.open(url, '_blank');
  };

or

  static openFileInTab = (blob: Blob) => {
    const url = URL.createObjectURL(blob);
    const anchor = document.createElement('a');
    anchor.href = url;
    anchor.target = '_blank';
    anchor.click();
  };

In Firefox both of the following methods work correctly, but not in Chrome/Edge.

How do I solve this problem?


问:
Firestore does not use sliding to delete Cell
I can delete Cell and firestore using swipe.
But I want to realize that each cell has a button that can be clicked to delete, such as the picture

This is my current code, I have tried for a long time and it is an error message
"Thread 1: "-[UIButton length]: unrecognized selector sent to instance 0x13111d4a0""Can anyone give me some advice? Thank you very much

This is my VC

```<code>class AiViewController: UIViewController, UITableViewDelegate, SkeletonTableViewDataSource, CustomTvCellDelegate {

 func delete(didSelectRowAt indexPath: IndexPath){

        self.db.collection("Users").document(UID!).collection("AiBuyPost").document("\(String(describing: self.postArray[indexPath.row].postID))").delete { error in

            self.postArray.remove(at: indexPath.row)
            self.liveTableView.reloadData()
        }

    }

 func delete(didSelectRowAt indexPath: IndexPath){

        self.db.collection("Users").document(UID!).collection("AiBuyPost").document("\(String(describing: self.postArray[indexPath.row].postID))").delete { error in

            self.postArray.remove(at: indexPath.row)
            self.liveTableView.reloadData()
        }

    }

</code>```

This is my Cell

```<code> weak var delegate: CustomTvCellDelegate?

 @IBAction func deletebtn(_ sender: UIButton) {

        delegate?.delete(didSelectRowAt: indexPath)

    }
</code>```

Body:
I can delete Cell and firestore using swipe.
But I want to realize that each cell has a button that can be clicked to delete, such as the picture

This is my current code, I have tried for a long time and it is an error message
"Thread 1: "-[UIButton length]: unrecognized selector sent to instance 0x13111d4a0""Can anyone give me some advice? Thank you very much

This is my VC

class AiViewController: UIViewController, UITableViewDelegate, SkeletonTableViewDataSource, CustomTvCellDelegate {

 func delete(didSelectRowAt indexPath: IndexPath){

        self.db.collection("Users").document(UID!).collection("AiBuyPost").document("\(String(describing: self.postArray[indexPath.row].postID))").delete { error in

            self.postArray.remove(at: indexPath.row)
            self.liveTableView.reloadData()
        }

    }

 func delete(didSelectRowAt indexPath: IndexPath){

        self.db.collection("Users").document(UID!).collection("AiBuyPost").document("\(String(describing: self.postArray[indexPath.row].postID))").delete { error in

            self.postArray.remove(at: indexPath.row)
            self.liveTableView.reloadData()
        }

    }

This is my Cell

 weak var delegate: CustomTvCellDelegate?

 @IBAction func deletebtn(_ sender: UIButton) {

        delegate?.delete(didSelectRowAt: indexPath)

    }


问:
debezium 2.0 connector sqlserver issue in mBean, JmxAttributeGauge
In older versions of Debezium using SQL Server as an example, metrics were available using the following naming strategy:

```<code>debezium.sql_server:type=connector-metrics,server=<sqlserver.server.name>,context=<context>

</code>```

In new release debezium 2.0, the naming strategy now includes a new task component in the JMX MBean name:

```<code>debezium.sql_server:type=connector-metrics,server=<sqlserver.server.name>,task=<task.id>,context=<context>
</code>```

I have created the objectName as per new naming strategy of debezium and passed to the JmxAttributeGauge. The values are not getting populated and null is coming on getValue()

```<code>objectName = new ObjectName("debezium.sql_server:type=connector-metrics,server=serverName,task=0,context=snapshot");

JmxAttributeGauge isSnapshotRunningJmx = new JmxAttributeGauge(objectName, "attribute_value");

System.out.println(isSnapshotRunningJmx.getValue()); // It returns null

</code>```

I have already verified the objectName from the Jconsole. It is correct.

Body:
In older versions of Debezium using SQL Server as an example, metrics were available using the following naming strategy:

debezium.sql_server:type=connector-metrics,server=<sqlserver.server.name>,context=<context>

In new release debezium 2.0, the naming strategy now includes a new task component in the JMX MBean name:

debezium.sql_server:type=connector-metrics,server=<sqlserver.server.name>,task=<task.id>,context=<context>

I have created the objectName as per new naming strategy of debezium and passed to the JmxAttributeGauge. The values are not getting populated and null is coming on getValue()

objectName = new ObjectName("debezium.sql_server:type=connector-metrics,server=serverName,task=0,context=snapshot");

JmxAttributeGauge isSnapshotRunningJmx = new JmxAttributeGauge(objectName, "attribute_value");

System.out.println(isSnapshotRunningJmx.getValue()); // It returns null

I have already verified the objectName from the Jconsole. It is correct.


问:
NUnit Playwright - Multiple inheritance BaseTests and PageTest
How to achieve the equivalent of multiple inheriting from a custom BaseTests class and Playwright's PageTest class?

Problem

I have 2 types of tests in my application: Non-playwright and Playwright-ones.

Both types share common SetUp code found in BaseTests and should inherit from BaseTests.

However, Playwright tests should also inherit from Playwright's PageTest.

I've tried making Playwright tests inherit from both BaseTests and PageTest, but multiple inheritance is not possible in C# AFAIK.

Solutions tried

(1) To make BaseTests an interface instead of a class. However, I found that NUnit doesn't call BaseTests's SetUp in that case.

(2) To add an abstract class BasePageTests : PageTest and duplicate the code of BaseTests in it. Actually, I do already have a BasePageTests since there's more SetUp code specific to Playwright only. But I'd rather make it BasePageTests: BaseTests, PageTest not duplicate the code of BaseTests's SetUp in BasePageTests.

Code

abstract class BaseTests {
  protected virtual CustomWebApplicationFactoryOptions? ConfigureCustomWebApplicationFactoryOptions() => null;

  [SetUp]
  public void BaseTestsSetUp() {
    // Lots of set-up code. E.g., cleaning up the database.
  }
}

class SampleNonPlaywrightTest : BaseTests {
  // ...
}

// `BasePageTests` needs `BaseTests`'s SetUp, but also has its own SetUp code.
// Needs to inherit from Playwright's `PageTest` (or make its children inherit from `PageTest`), but multiple inheritance is not possible!
abstract class BasePageTests : BaseTests, PageTest {
    protected override CustomWebApplicationFactoryOptions? ConfigureCustomWebApplicationFactoryOptions() =>
        new() { StartRealServer = true, BypassAuth = true };

  [SetUp]
  public void BasePageTestsSetUp() {
    // More set-up relevant only to page tests. E.g., calling `_application.CreateClient()` to actually start the server
  }
}

class SamplePlaywrightTest : BasePageTests {
  // ...
}
```

So, in summary: What is the idiomatic way to achieve the above without code duplication?

Body:
How to achieve the equivalent of multiple inheriting from a custom BaseTests class and Playwright's PageTest class?

Problem

I have 2 types of tests in my application: Non-playwright and Playwright-ones.

Both types share common SetUp code found in BaseTests and should inherit from BaseTests.

However, Playwright tests should also inherit from Playwright's PageTest.

I've tried making Playwright tests inherit from both BaseTests and PageTest, but multiple inheritance is not possible in C# AFAIK.

Solutions tried

(1) To make BaseTests an interface instead of a class. However, I found that NUnit doesn't call BaseTests's SetUp in that case.

(2) To add an abstract class BasePageTests : PageTest and duplicate the code of BaseTests in it. Actually, I do already have a BasePageTests since there's more SetUp code specific to Playwright only. But I'd rather make it BasePageTests: BaseTests, PageTest not duplicate the code of BaseTests's SetUp in BasePageTests.

Code

abstract class BaseTests {
  protected virtual CustomWebApplicationFactoryOptions? ConfigureCustomWebApplicationFactoryOptions() => null;

  [SetUp]
  public void BaseTestsSetUp() {
    // Lots of set-up code. E.g., cleaning up the database.
  }
}

class SampleNonPlaywrightTest : BaseTests {
  // ...
}

// `BasePageTests` needs `BaseTests`'s SetUp, but also has its own SetUp code.
// Needs to inherit from Playwright's `PageTest` (or make its children inherit from `PageTest`), but multiple inheritance is not possible!
abstract class BasePageTests : BaseTests, PageTest {
    protected override CustomWebApplicationFactoryOptions? ConfigureCustomWebApplicationFactoryOptions() =>
        new() { StartRealServer = true, BypassAuth = true };

  [SetUp]
  public void BasePageTestsSetUp() {
    // More set-up relevant only to page tests. E.g., calling `_application.CreateClient()` to actually start the server
  }
}

class SamplePlaywrightTest : BasePageTests {
  // ...
}

So, in summary: What is the idiomatic way to achieve the above without code duplication?


问:
can not cast servletrequest to HttpServletRequest
I can cast servletrequest to HttpServletRequest  in doFilterInternal method. I'm receiving the following error:

```<code>java.lang.ClassCastException: class org.springframework.security.web.firewall.StrictHttpFirewall$StrictFirewalledRequest cannot be cast to class javax.servlet.http.HttpServletRequest (org.springframework.security.web.firewall.StrictHttpFirewall$StrictFirewalledRequest and javax.servlet.http.HttpServletRequest are in unnamed module of loader 'app')
</code>```

The expected is to get the authorization from the header using:

httpRequest.getHeader("Authorization");
```
<pre class="lang-java prettyprint-override"><code>@Override
public void doFilter(jakarta.servlet.ServletRequest request, jakarta.servlet.ServletResponse response,
        jakarta.servlet.FilterChain chain) throws IOException, jakarta.servlet.ServletException {
    // TODO Auto-generated method stub

    String token = jwtTokenProvider.resolveToken(request);

    if (token != null && jwtTokenProvider.validateToken(token)) {
        Authentication auth = jwtTokenProvider.getAuthentication(token);
        if (auth != null) {
            SecurityContextHolder.getContext().setAuthentication(auth);
        }
    }
    chain.doFilter(request, response);
}
</code>```

Body:
I can cast servletrequest to HttpServletRequest  in doFilterInternal method. I'm receiving the following error:

java.lang.ClassCastException: class org.springframework.security.web.firewall.StrictHttpFirewall$StrictFirewalledRequest cannot be cast to class javax.servlet.http.HttpServletRequest (org.springframework.security.web.firewall.StrictHttpFirewall$StrictFirewalledRequest and javax.servlet.http.HttpServletRequest are in unnamed module of loader 'app')

The expected is to get the authorization from the header using:

httpRequest.getHeader("Authorization");

@Override
public void doFilter(jakarta.servlet.ServletRequest request, jakarta.servlet.ServletResponse response,
        jakarta.servlet.FilterChain chain) throws IOException, jakarta.servlet.ServletException {
    // TODO Auto-generated method stub

    String token = jwtTokenProvider.resolveToken(request);

    if (token != null && jwtTokenProvider.validateToken(token)) {
        Authentication auth = jwtTokenProvider.getAuthentication(token);
        if (auth != null) {
            SecurityContextHolder.getContext().setAuthentication(auth);
        }
    }
    chain.doFilter(request, response);
}


问:
How to use mongo stable api by mongoose?
Here is my code. I can't find the way on mongodb website.

```<code>mongoose.connect(url, { useNewUrlParser: true , autoIndex: false })
</code>```

I tried to add serverApi but it didn't seems work.

```<code>mongoose.connect(url, { useNewUrlParser: true , autoIndex: false , serverApi: { version: '1' } })
</code>```

Body:
Here is my code. I can't find the way on mongodb website.

mongoose.connect(url, { useNewUrlParser: true , autoIndex: false })

I tried to add serverApi but it didn't seems work.

mongoose.connect(url, { useNewUrlParser: true , autoIndex: false , serverApi: { version: '1' } })


问:
How to verify whether .wav file is playing audio in web page?
I have a feature which plays audio (.wav) file on web browser. I need to verify whether the audio is playing in my tests. Is there any JS library or api utils or any Playwright feature available to test this?</p>


问:
Swiper Js Vue3 Vertical
I am having an issue with the swiper vertical, when I swiped once it goes to the last slide instead of the next slide.

I am using vue3, typescript, and swiper vue.

```<code><script setup lang="ts">

import { Swiper, SwiperSlide } from 'swiper/vue'
import 'swiper/css'

</script>

<template>
  <main>
    <swiper
      :direction="'vertical'"
    >
      <swiper-slide class="h-screen bg-yellow-100">
        1
      </swiper-slide>
      <swiper-slide class="h-screen bg-green-100">

        2
      </swiper-slide>
      <swiper-slide class="h-screen bg-orange-100">

        3
      </swiper-slide>
      <swiper-slide class="h-screen bg-violet-100">

        4
      </swiper-slide>
    </swiper>
  </main>
</template>
</code>```

Any help would be appreciated...

Title: Swiper Js Vue3 Vertical

Body:
I am having an issue with the swiper vertical, when I swiped once it goes to the last slide instead of the next slide.

I am using vue3, typescript, and swiper vue.

<template>

    <swiper
      :direction="'vertical'"
    >
      <swiper-slide class="h-screen bg-yellow-100">
        1
      </swiper-slide>
      <swiper-slide class="h-screen bg-green-100">

        2
      </swiper-slide>
      <swiper-slide class="h-screen bg-orange-100">

        3
      </swiper-slide>
      <swiper-slide class="h-screen bg-violet-100">

        4
      </swiper-slide>
    </swiper>

</template>

Any help would be appreciated...


问:
Is there a proper way to make a two distincts states program in processing?
For a project, I need to do a processing code able to switch between two completely different states. There is a default state and it switches to the special state when the mouse is pressed. The special state have an initialization phase. It also have an end and when it reaches it, the program switches back to the normal state. The way I would implement this is the following :

```<code>boolean isNormal;

void setup(){
  //setup things...
  isNormal = true;
}

void draw(){
  if(isNormal){
    normal();
  }
  else{
    special();
    if (endReached){
      isNormal = true;
    }
  }
}

void mousePressed(){
  specialSetup();
  isNormal = false;
}

void normal(){
  //normal routine...
}

void special(){
  //special routine...
}
</code>```

Is there a better way to do it (more efficient, cleaner, ...) ?

Body:
For a project, I need to do a processing code able to switch between two completely different states. There is a default state and it switches to the special state when the mouse is pressed. The special state have an initialization phase. It also have an end and when it reaches it, the program switches back to the normal state. The way I would implement this is the following :

boolean isNormal;

void setup(){
  //setup things...
  isNormal = true;
}

void draw(){
  if(isNormal){
    normal();
  }
  else{
    special();
    if (endReached){
      isNormal = true;
    }
  }
}

void mousePressed(){
  specialSetup();
  isNormal = false;
}

void normal(){
  //normal routine...
}

void special(){
  //special routine...
}

Is there a better way to do it (more efficient, cleaner, ...) ?


问:
when using react simple maps showing svg error?
When i am using react-simple-maps an error showing, I can't find the solution anywhere.

ERROR  Invariant Violation: View config getter callback for component svg must be a function (received undefined). Make sure to start component names with a capital letter.

```<code>This error is located at:
    in svg (created by ComposableMap)
    in k (created by ComposableMap)
    in ComposableMap (created by CountryDetailScreen)
    in RCTView (created by View)
    in View (created by CountryDetailScreen)
    in RNCSafeAreaView
    in Unknown (created by Screen)
    in Screen (created by CountryDetailScreen)
    in CountryDetailScreen (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by SceneView)
    in RCTView (created by View)
    in View (created by DebugContainer)
    in DebugContainer (created by MaybeNestedStack)
    in MaybeNestedStack (created by SceneView)
    in RCTView (created by View)
    in View (created by SceneView)
    in RNSScreen (created by AnimatedComponent)
    in AnimatedComponent
    in AnimatedComponentWrapper (created by InnerScreen)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by InnerScreen)
    in InnerScreen (created by Screen)
    in Screen (created by SceneView)
    in SceneView (created by NativeStackViewInner)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by ScreenStack)
    in RNSScreenStack (created by ScreenStack)
    in ScreenStack (created by NativeStackViewInner)
    in NativeStackViewInner (created by NativeStackView)
    in RCTView (created by View)
    in View (created by SafeAreaInsetsContext)
    in SafeAreaProviderCompat (created by NativeStackView)
    in NativeStackView (created by NativeStackNavigator)
    in PreventRemoveProvider (created by NavigationContent)
    in NavigationContent
    in Unknown (created by NativeStackNavigator)
    in NativeStackNavigator (created by Navigator)
    in AppBootstrapGate (created by Navigator)
    in EnsureSingleNavigator
    in BaseNavigationContainer
    in ThemeProvider
    in NavigationContainerInner (created by Navigator)
    in Navigator (created by Main)
    in Provider (created by Main)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by Main)
    in Main
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
    in QuobPad(RootComponent)
</code>```

Body:
When i am using react-simple-maps an error showing, I can't find the solution anywhere.

ERROR  Invariant Violation: View config getter callback for component svg must be a function (received undefined). Make sure to start component names with a capital letter.

This error is located at:
    in svg (created by ComposableMap)
    in k (created by ComposableMap)
    in ComposableMap (created by CountryDetailScreen)
    in RCTView (created by View)
    in View (created by CountryDetailScreen)
    in RNCSafeAreaView
    in Unknown (created by Screen)
    in Screen (created by CountryDetailScreen)
    in CountryDetailScreen (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by SceneView)
    in RCTView (created by View)
    in View (created by DebugContainer)
    in DebugContainer (created by MaybeNestedStack)
    in MaybeNestedStack (created by SceneView)
    in RCTView (created by View)
    in View (created by SceneView)
    in RNSScreen (created by AnimatedComponent)
    in AnimatedComponent
    in AnimatedComponentWrapper (created by InnerScreen)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by InnerScreen)
    in InnerScreen (created by Screen)
    in Screen (created by SceneView)
    in SceneView (created by NativeStackViewInner)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by ScreenStack)
    in RNSScreenStack (created by ScreenStack)
    in ScreenStack (created by NativeStackViewInner)
    in NativeStackViewInner (created by NativeStackView)
    in RCTView (created by View)
    in View (created by SafeAreaInsetsContext)
    in SafeAreaProviderCompat (created by NativeStackView)
    in NativeStackView (created by NativeStackNavigator)
    in PreventRemoveProvider (created by NavigationContent)
    in NavigationContent
    in Unknown (created by NativeStackNavigator)
    in NativeStackNavigator (created by Navigator)
    in AppBootstrapGate (created by Navigator)
    in EnsureSingleNavigator
    in BaseNavigationContainer
    in ThemeProvider
    in NavigationContainerInner (created by Navigator)
    in Navigator (created by Main)
    in Provider (created by Main)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by Main)
    in Main
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
    in QuobPad(RootComponent)


问:
Establish SFTP connection within an app that runs from a WAR file
I have to establish the SFTP connection within a Spring Boot app that runs from a WAR file.
Before posting this I’ve tried the suggestions from the following threads:

Cannot be resolved to absolute file path because it does not reside in the file system

File path to resource in our war/WEB-INF folder?

SFTP Inbound Sync Fails when deployed as war

The application is built as a WAR file, and I used the JSch library in order to establish the SFTP connection. The setup for this library implies usage of its addIdentity method, where the first argument/parameter should be the path to the Private Key file (the content is not passed directly).

If I run the app within and IDE, then the SFTP connection can be established and it works. But if I build the app as a WAR file, and I run it from that WAR file, then the SFTP connection cannot be established, because the Private Key file cannot be found.

I run the WAR file by executing this command within a CLI, from the location of that WAR file:
java -jar  test_sftp_in_war_file-0.0.1-SNAPSHOT.war

The Private Key file was added to the resources directory from the Spring Boot project.

This image contains the structure of the Private Key, generated using PuttyGen with RSA encryption (not OpenSSH)

This image contains the location of the Private Key within the generated WAR file

The passphrase is being read and passed correctly. The issue is the path to the Private Key file.

I use the pom.xml file, with the following Maven dependencies:

```<code><?xml ...>
    <packaging>war</packaging>  <!-- to build the project as a WAR file -->
    <name>test_sftp_in_war_file</name>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- dependency for the JSch SFTP library -->
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-sftp</artifactId>
            <version>5.5.15</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>
</code>```

This is the code that I've tried:

```<code>import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletContext;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.FileOutputStream;
import java.util.UUID;
import org.apache.commons.io.IOUtils;
import java.net.URL;
import java.net.URLDecoder;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@Slf4j
@RequiredArgsConstructor
public class SftpExample {

    private final ServletContext context;

    public static void main(String[] args) throws JSchException, IOException {
        SpringApplication.run(TestSftpInWarFileApplication.class, args);
    }

    public void fetchData() throws Exception {
        JSch jSch = new JSch();
        Session session = null;
        Channel channel = null;
        ChannelSftp channelSftp = null;
        String devServerPath = "/proprietary/path/on/sftp/server";

        String filePath;

        Path tempFile = null;
        InputStream inputStream;
        FileOutputStream out;

        try {
            // version 1
            /** => the filePath is retrieved, but the error occurs when it is passed to the addIdentity method
             * >>> filePath = C:\projects\test_sftp_in_war_file\target\private-key.ppk
             * com.jcraft.jsch.JSchException: java.io.FileNotFoundException: C:\projects\test_sftp_in_war_file\target\private-key.ppk
             * (The system cannot find the file specified)
             *         at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
             *         at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
             *         at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:172)
             */
            filePath = Paths.get("private-key.ppk").toAbsolutePath().toString();

            // version 2
            /** => the filePath is retrieved, but the error occurs when it is passed to the addIdentity method
             * >>> filePath = jar:file:/C:/projects/test_sftp_in_war_file/target/test_sftp_in_war_file-0.0.1-SNAPSHOT.war!/WEB-INF/classes!/private-key.ppk
             * com.jcraft.jsch.JSchException: java.io.FileNotFoundException: jar:file:\C:\projects\test_sftp_in_war_file\target\test_sftp_in_war_file-0.0.1-SNAPSHOT.war!\WEB-INF\classes!\private-key.ppk
             * (The filename, directory name, or volume label syntax is incorrect)
             *         at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
             *         at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
             *         at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:162)
             */
            filePath = this.getClass().getClassLoader().getResource("private-key.ppk").toExternalForm();

            // version 3
            /** => the filePath is retrieved, but the error occurs when it is passed to the addIdentity method
             * >>> filePath = file:/C:/projects/test_sftp_in_war_file/target/classes/private-key.ppk
             * java.lang.NullPointerException: null
             *         at com.jcraft.jsch.Util.checkTilde(Util.java:489) ~[jsch-0.1.55.jar!/:na]
             *         at com.jcraft.jsch.Util.fromFile(Util.java:506) ~[jsch-0.1.55.jar!/:na]
             *         at com.jcraft.jsch.KeyPair.load(KeyPair.java:540) ~[jsch-0.1.55.jar!/:na]
             *         at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40) ~[jsch-0.1.55.jar!/:na]
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:406) ~[jsch-0.1.55.jar!/:na]
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:387) ~[jsch-0.1.55.jar!/:na]
             *         at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:148)
             */
            File privateKeyFile = new ClassPathResource("private-key.ppk").getFile();   // getting the file content
            filePath = privateKeyFile.toURI().toString();

            // version 4 => read the content and generate a new temporary file, and pass the path to that temp file
            /** => this workaround works when running the local WAR, but does not run in the cloud environment
             * >>> filePath = C:\Users\USER\AppData\Local\Temp\private-key_3ca449c2-0ed1-459c-a2cd-70f51f4023eb2105597171450888881.ppk
             */
            inputStream = new ClassPathResource("private-key.ppk").getInputStream();
            tempFile = File.createTempFile("private_key_" + UUID.randomUUID().toString(), ".ppk").toPath();
            out = new FileOutputStream(tempFile.toFile());
            IOUtils.copy(inputStream, out);
            filePath = tempFile.toFile().getAbsolutePath();

            // version 5
            /** => the filePath is retrieved, but the error occurs when it is passed to the addIdentity method
             * >>> filePath = file:\C:\projects\test_sftp_in_war_file\target\test_sftp_in_war_file-0.0.1-SNAPSHOT.war*\WEB-INF\classes\private-key.ppk
             * com.jcraft.jsch.JSchException: java.io.FileNotFoundException: file:\C:\projects\test_sftp_in_war_file\target\test_sftp_in_war_file-0.0.1-SNAPSHOT.war*\WEB-INF\classes\private-key.ppk
             * (The filename, directory name, or volume label syntax is incorrect)
             *      at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
             *      at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
             *      at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:95)
             */
            URL resourceUrl = context.getResource("/WEB-INF/classes/private-key.ppk");
            filePath = resourceUrl.getPath();

            // version 6
             * >>> filePath = sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@704b2127
             * com.jcraft.jsch.JSchException: java.io.FileNotFoundException: sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@704b2127
             * (The system cannot find the file specified)
             *      at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
             *      at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
             *      at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:95)
             */
            filePath = getClass().getResourceAsStream("/WEB-INF/classes/private-key.ppk").toString();

            // version 7
            /** => the filePath is retrieved, but the error occurs when it is passed to the addIdentity method
             * >>> filePath = file:\C:\projects\test_sftp_in_war_file\target\test_sftp_in_war_file-0.0.1-SNAPSHOT.war!\WEB-INF\classes!\private-key.ppk
             * com.jcraft.jsch.JSchException: java.io.FileNotFoundException: file:\C:\projects\test_sftp_in_war_file\target\test_sftp_in_war_file-0.0.1-SNAPSHOT.war!\WEB-INF\classes!\private-key.ppk
             * (The filename, directory name, or volume label syntax is incorrect)
             *      at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
             *      at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
             *      at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:95)
             */
            filePath = getClass().getClassLoader().getResource("private-key.ppk").getPath();

            // version 8
            /**
             * java.lang.NullPointerException: null
             *      at com.jcraft.jsch.Util.checkTilde(Util.java:489)
             *      at com.jcraft.jsch.Util.fromFile(Util.java:506)
             */
            filePath = SftpExample.class.getResource("private-key.ppk").getPath();

            // version 9
            /**
             * java.lang.NullPointerException: null
             *      at com.jcraft.jsch.Util.checkTilde(Util.java:489)
             *      at com.jcraft.jsch.Util.fromFile(Util.java:506)
             */
            filePath = URLDecoder.decode(SftpExample.class.getResource("private-key.ppk").getPath(), "UTF-8");   // Application run failed: java.lang.NullPointerException: null

            // version 10
            /**
             * java.lang.NullPointerException: null
             *      at com.jcraft.jsch.Util.checkTilde(Util.java:489)
             *      at com.jcraft.jsch.Util.fromFile(Util.java:506)
             */
//          filePath = context.getRealPath("/WEB-INF/classes/private-key.ppk");

            log.info(">>> filePath = " + filePath);
        } catch (NullPointerException e) {
            // throw new Exception("Could not be retrieved the path for this file: " + "private-key.ppk");
            log.error(Arrays.toString(e.getStackTrace()));
        }

        try {
            jSch.addIdentity(filePath, "passphrase_is_correct");   // the error is generated at this line
            session = jSch.getSession("username", "host", 22);  // this is where the connection should be established
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");  // by default, say that we trust the specified server (to not be required to explicitly say that we trust it for each connection)
            session.setConfig(config);
            session.connect();
            channel = session.openChannel("sftp");
            channel.connect();
            channelSftp = (ChannelSftp) channel;

            // other operations that occur once the SFTP connection is established

            log.info(">>> the SFTP connection was established successfully");
        } catch (JSchException e) {
            e.printStackTrace();
        } finally {
            if (session != null && channel != null) {
                channel.disconnect();
                session.disconnect();
            }

            inputStream.close();
            out.close();
        }
    }

    @EventListener(ContextRefreshedEvent.class) // waits to be finished the Spring Context initialization
    public void run1() throws Exception {
        this.fetchData();
    }
}
</code>```

This is the stack trace that was generated for version 5:

```<code>2023-01-03 17:19:32.413 ERROR 25960 --- [           main] o.s.boot.SpringApplication               : Application run failed
Bean [com.example.test_sftp_in_war_file.SftpExample]
Method [public void com.example.test_sftp_in_war_file.SftpExample throws java.lang.Exception]
Method [public void com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.run1() throws java.lang.Exception]
Resolved arguments:

        at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:361) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.main(TestSftpInWarFileApplication.java:42) ~[classes!/:0.0.1-SNAPSHOT]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[test_sftp_in_war_file-0.0.1-SNAPSHOT.war:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[test_sftp_in_war_file-0.0.1-SNAPSHOT.war:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[test_sftp_in_war_file-0.0.1-SNAPSHOT.war:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59) ~[test_sftp_in_war_file-0.0.1-SNAPSHOT.war:0.0.1-SNAPSHOT]
Caused by: java.lang.Exception: Could not be retrieved the path for this file: private-key.ppk
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.fetchData(TestSftpInWarFileApplication.java:86) ~[classes!/:0.0.1-SNAPSHOT]
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.run1(TestSftpInWarFileApplication.java:118) ~[classes!/:0.0.1-SNAPSHOT]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
        at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344) ~[spring-context-5.3.24.jar!/:5.3.24]
        ... 24 common frames omitted
</code>```

This is the stack trace generated for version 6 and 7:

```<code>2023-01-04 11:09:30.661  INFO 29328 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8090 (http) with context path ''
2023-01-04 11:09:30.670  INFO 29328 --- [           main] c.e.t.TestSftpInWarFileApplication       : >>> filePath = sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@7cc9ce8
com.jcraft.jsch.JSchException: java.io.FileNotFoundException: sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@7cc9ce8 (The system cannot find the file specified)
        at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
        at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
        at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
        at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.fetchData(TestSftpInWarFileApplication.java:90)
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.run1(TestSftpInWarFileApplication.java:118)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344)
        at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229)
        at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378)
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.main(TestSftpInWarFileApplication.java:42)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59)
Caused by: java.io.FileNotFoundException: sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@7cc9ce8 (The system cannot find the file specified)
        at java.base/java.io.FileInputStream.open0(Native Method)
        at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:112)
        at com.jcraft.jsch.Util.fromFile(Util.java:508)
        at com.jcraft.jsch.KeyPair.load(KeyPair.java:540)
        ... 34 more

</code>```

Body:
I have to establish the SFTP connection within a Spring Boot app that runs from a WAR file.
Before posting this I’ve tried the suggestions from the following threads:

Cannot be resolved to absolute file path because it does not reside in the file system

File path to resource in our war/WEB-INF folder?

SFTP Inbound Sync Fails when deployed as war

The application is built as a WAR file, and I used the JSch library in order to establish the SFTP connection. The setup for this library implies usage of its addIdentity method, where the first argument/parameter should be the path to the Private Key file (the content is not passed directly).

If I run the app within and IDE, then the SFTP connection can be established and it works. But if I build the app as a WAR file, and I run it from that WAR file, then the SFTP connection cannot be established, because the Private Key file cannot be found.

I run the WAR file by executing this command within a CLI, from the location of that WAR file:
java -jar  test_sftp_in_war_file-0.0.1-SNAPSHOT.war

The Private Key file was added to the resources directory from the Spring Boot project.

This image contains the structure of the Private Key, generated using PuttyGen with RSA encryption (not OpenSSH)

This image contains the location of the Private Key within the generated WAR file

The passphrase is being read and passed correctly. The issue is the path to the Private Key file.

I use the pom.xml file, with the following Maven dependencies:

<?xml ...>
    <packaging>war</packaging>
    <name>test_sftp_in_war_file</name>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-sftp</artifactId>
            <version>5.5.15</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

This is the code that I've tried:

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletContext;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.FileOutputStream;
import java.util.UUID;
import org.apache.commons.io.IOUtils;
import java.net.URL;
import java.net.URLDecoder;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@Slf4j
@RequiredArgsConstructor
public class SftpExample {

    private final ServletContext context;

    public static void main(String[] args) throws JSchException, IOException {
        SpringApplication.run(TestSftpInWarFileApplication.class, args);
    }

    public void fetchData() throws Exception {
        JSch jSch = new JSch();
        Session session = null;
        Channel channel = null;
        ChannelSftp channelSftp = null;
        String devServerPath = "/proprietary/path/on/sftp/server";

        String filePath;

        Path tempFile = null;
        InputStream inputStream;
        FileOutputStream out;

        try {
            // version 1
            /** => the filePath is retrieved, but the error occurs when it is passed to the addIdentity method
             * >>> filePath = C:\projects\test_sftp_in_war_file\target\private-key.ppk
             * com.jcraft.jsch.JSchException: java.io.FileNotFoundException: C:\projects\test_sftp_in_war_file\target\private-key.ppk
             * (The system cannot find the file specified)
             *         at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
             *         at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
             *         at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:172)
             */
            filePath = Paths.get("private-key.ppk").toAbsolutePath().toString();

            // version 2
            /** => the filePath is retrieved, but the error occurs when it is passed to the addIdentity method
             * >>> filePath = jar:file:/C:/projects/test_sftp_in_war_file/target/test_sftp_in_war_file-0.0.1-SNAPSHOT.war!/WEB-INF/classes!/private-key.ppk
             * com.jcraft.jsch.JSchException: java.io.FileNotFoundException: jar:file:\C:\projects\test_sftp_in_war_file\target\test_sftp_in_war_file-0.0.1-SNAPSHOT.war!\WEB-INF\classes!\private-key.ppk
             * (The filename, directory name, or volume label syntax is incorrect)
             *         at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
             *         at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
             *         at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:162)
             */
            filePath = this.getClass().getClassLoader().getResource("private-key.ppk").toExternalForm();

            // version 3
            /** => the filePath is retrieved, but the error occurs when it is passed to the addIdentity method
             * >>> filePath = file:/C:/projects/test_sftp_in_war_file/target/classes/private-key.ppk
             * java.lang.NullPointerException: null
             *         at com.jcraft.jsch.Util.checkTilde(Util.java:489) ~[jsch-0.1.55.jar!/:na]
             *         at com.jcraft.jsch.Util.fromFile(Util.java:506) ~[jsch-0.1.55.jar!/:na]
             *         at com.jcraft.jsch.KeyPair.load(KeyPair.java:540) ~[jsch-0.1.55.jar!/:na]
             *         at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40) ~[jsch-0.1.55.jar!/:na]
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:406) ~[jsch-0.1.55.jar!/:na]
             *         at com.jcraft.jsch.JSch.addIdentity(JSch.java:387) ~[jsch-0.1.55.jar!/:na]
             *         at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:148)
             */
            File privateKeyFile = new ClassPathResource("private-key.ppk").getFile();   // getting the file content
            filePath = privateKeyFile.toURI().toString();

            // version 4 => read the content and generate a new temporary file, and pass the path to that temp file
            /** => this workaround works when running the local WAR, but does not run in the cloud environment
             * >>> filePath = C:\Users\USER\AppData\Local\Temp\private-key_3ca449c2-0ed1-459c-a2cd-70f51f4023eb2105597171450888881.ppk
             */
            inputStream = new ClassPathResource("private-key.ppk").getInputStream();
            tempFile = File.createTempFile("private_key_" + UUID.randomUUID().toString(), ".ppk").toPath();
            out = new FileOutputStream(tempFile.toFile());
            IOUtils.copy(inputStream, out);
            filePath = tempFile.toFile().getAbsolutePath();

            // version 5
            /** => the filePath is retrieved, but the error occurs when it is passed to the addIdentity method
             * >>> filePath = file:\C:\projects\test_sftp_in_war_file\target\test_sftp_in_war_file-0.0.1-SNAPSHOT.war*\WEB-INF\classes\private-key.ppk
             * com.jcraft.jsch.JSchException: java.io.FileNotFoundException: file:\C:\projects\test_sftp_in_war_file\target\test_sftp_in_war_file-0.0.1-SNAPSHOT.war*\WEB-INF\classes\private-key.ppk
             * (The filename, directory name, or volume label syntax is incorrect)
             *      at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
             *      at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
             *      at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:95)
             */
            URL resourceUrl = context.getResource("/WEB-INF/classes/private-key.ppk");
            filePath = resourceUrl.getPath();

            // version 6
             * >>> filePath = sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@704b2127
             * com.jcraft.jsch.JSchException: java.io.FileNotFoundException: sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@704b2127
             * (The system cannot find the file specified)
             *      at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
             *      at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
             *      at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:95)
             */
            filePath = getClass().getResourceAsStream("/WEB-INF/classes/private-key.ppk").toString();

            // version 7
            /** => the filePath is retrieved, but the error occurs when it is passed to the addIdentity method
             * >>> filePath = file:\C:\projects\test_sftp_in_war_file\target\test_sftp_in_war_file-0.0.1-SNAPSHOT.war!\WEB-INF\classes!\private-key.ppk
             * com.jcraft.jsch.JSchException: java.io.FileNotFoundException: file:\C:\projects\test_sftp_in_war_file\target\test_sftp_in_war_file-0.0.1-SNAPSHOT.war!\WEB-INF\classes!\private-key.ppk
             * (The filename, directory name, or volume label syntax is incorrect)
             *      at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
             *      at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
             *      at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
             *      at com.example.test_sftp_in_war_file.SftpExample.fetchData(SftpExample.java:95)
             */
            filePath = getClass().getClassLoader().getResource("private-key.ppk").getPath();

            // version 8
            /**
             * java.lang.NullPointerException: null
             *      at com.jcraft.jsch.Util.checkTilde(Util.java:489)
             *      at com.jcraft.jsch.Util.fromFile(Util.java:506)
             */
            filePath = SftpExample.class.getResource("private-key.ppk").getPath();

            // version 9
            /**
             * java.lang.NullPointerException: null
             *      at com.jcraft.jsch.Util.checkTilde(Util.java:489)
             *      at com.jcraft.jsch.Util.fromFile(Util.java:506)
             */
            filePath = URLDecoder.decode(SftpExample.class.getResource("private-key.ppk").getPath(), "UTF-8");   // Application run failed: java.lang.NullPointerException: null

            // version 10
            /**
             * java.lang.NullPointerException: null
             *      at com.jcraft.jsch.Util.checkTilde(Util.java:489)
             *      at com.jcraft.jsch.Util.fromFile(Util.java:506)
             */
//          filePath = context.getRealPath("/WEB-INF/classes/private-key.ppk");

            log.info(">>> filePath = " + filePath);
        } catch (NullPointerException e) {
            // throw new Exception("Could not be retrieved the path for this file: " + "private-key.ppk");
            log.error(Arrays.toString(e.getStackTrace()));
        }

        try {
            jSch.addIdentity(filePath, "passphrase_is_correct");   // the error is generated at this line
            session = jSch.getSession("username", "host", 22);  // this is where the connection should be established
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");  // by default, say that we trust the specified server (to not be required to explicitly say that we trust it for each connection)
            session.setConfig(config);
            session.connect();
            channel = session.openChannel("sftp");
            channel.connect();
            channelSftp = (ChannelSftp) channel;

            // other operations that occur once the SFTP connection is established

            log.info(">>> the SFTP connection was established successfully");
        } catch (JSchException e) {
            e.printStackTrace();
        } finally {
            if (session != null && channel != null) {
                channel.disconnect();
                session.disconnect();
            }

            inputStream.close();
            out.close();
        }
    }

    @EventListener(ContextRefreshedEvent.class) // waits to be finished the Spring Context initialization
    public void run1() throws Exception {
        this.fetchData();
    }
}

This is the stack trace that was generated for version 5:

2023-01-03 17:19:32.413 ERROR 25960 --- [           main] o.s.boot.SpringApplication               : Application run failed
Bean [com.example.test_sftp_in_war_file.SftpExample]
Method [public void com.example.test_sftp_in_war_file.SftpExample throws java.lang.Exception]
Method [public void com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.run1() throws java.lang.Exception]
Resolved arguments:

        at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:361) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.24.jar!/:5.3.24]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-2.7.7.jar!/:2.7.7]
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.main(TestSftpInWarFileApplication.java:42) ~[classes!/:0.0.1-SNAPSHOT]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[test_sftp_in_war_file-0.0.1-SNAPSHOT.war:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[test_sftp_in_war_file-0.0.1-SNAPSHOT.war:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[test_sftp_in_war_file-0.0.1-SNAPSHOT.war:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59) ~[test_sftp_in_war_file-0.0.1-SNAPSHOT.war:0.0.1-SNAPSHOT]
Caused by: java.lang.Exception: Could not be retrieved the path for this file: private-key.ppk
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.fetchData(TestSftpInWarFileApplication.java:86) ~[classes!/:0.0.1-SNAPSHOT]
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.run1(TestSftpInWarFileApplication.java:118) ~[classes!/:0.0.1-SNAPSHOT]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
        at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344) ~[spring-context-5.3.24.jar!/:5.3.24]
        ... 24 common frames omitted

This is the stack trace generated for version 6 and 7:

2023-01-04 11:09:30.661  INFO 29328 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8090 (http) with context path ''
2023-01-04 11:09:30.670  INFO 29328 --- [           main] c.e.t.TestSftpInWarFileApplication       : >>> filePath = sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@7cc9ce8
com.jcraft.jsch.JSchException: java.io.FileNotFoundException: sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@7cc9ce8 (The system cannot find the file specified)
        at com.jcraft.jsch.KeyPair.load(KeyPair.java:543)
        at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
        at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
        at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.fetchData(TestSftpInWarFileApplication.java:90)
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.run1(TestSftpInWarFileApplication.java:118)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344)
        at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229)
        at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378)
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
        at com.example.test_sftp_in_war_file.TestSftpInWarFileApplication.main(TestSftpInWarFileApplication.java:42)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59)
Caused by: java.io.FileNotFoundException: sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@7cc9ce8 (The system cannot find the file specified)
        at java.base/java.io.FileInputStream.open0(Native Method)
        at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:112)
        at com.jcraft.jsch.Util.fromFile(Util.java:508)
        at com.jcraft.jsch.KeyPair.load(KeyPair.java:540)
        ... 34 more


问:
Prestashop 1.7 Update shipping cost programatically through ajax when changing payment method
I have created one custom shipping module in Prestashop 1.7 which will list multiple shipping carriers (like DHL, Fedex etc) on checkout page and in-order to fetch their shipping cost, i am calling their respective API by passing parameters of products like Size,,Weight,Length,Width etc.. to fetch their shipping cost. https://prnt.sc/LzQlgXZdPv3W

Now if we select Cash on Delivery payment method then i need to again call shipping carrier api to fetch new shipping price as shipping price will be different based on Cash on Delivery Payment method. Because COD payment method will be having higher shipping price as compare with other payment methods like Credit Card, Debit card etc.

Can anyone know how we can achieve this functionality ? as i need to update shipping price (by calling their API) through ajax when we change payment method on checkout page.


问:
How to programmatically enable airplane mode on Android?
I'm trying to programmatically enable/disable Airplane mode on Android.

Requested the following permissions in the manifest:

```<code><uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
</code>```

And using the following code:

```<code>String[] task = new String[] { "su", "settings put global airplane_mode_on 1", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true" };
try {
  Process process = Runtime.getRuntime().exec(task);
  process.waitFor();
} catch (IOException e) {

}catch (SecurityException e){

}catch (Exception e) {

}
</code>```

This works correctly for rooted Meizu 5 (Android 6.0).
But it doesn't work for rooted Samsung S4 (Android 5.0.1) and Alcatel 5033D (Android 8.1.0) :(

When I used adb commands connecting phone to computer it worked correctly for Samsung:

```<code>adb shell settings put global airplane_mode_on 1
adb shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true
</code>```

In some publics I saw advice in dividing the execution of a line in two stages:

"settings put global airplane_mode_on 1; am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true" };

"settings put global airplane_mode_on 1 && am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true"
But it did not help.

Tried another way:

```<code>String[][] t = new String[][]{new String[] { "su", "settings put global airplane_mode_on 1"},new String[] {"su","am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true" }};
//String[][] t = new String[][]{new String[] { "su", "settings put global airplane_mode_on 1"},new String[] {"am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true" }};
 try {
  Process process = null;
  for (String[] s : t) {
    process  = Runtime.getRuntime().exec(s);
  }
  process.waitFor();
}catch (IOException e) {
}catch (SecurityException e){
}catch (Exception e) {
}
</code>```

But it also did not bring a positive result.

Body:
I'm trying to programmatically enable/disable Airplane mode on Android.

Requested the following permissions in the manifest:

<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

And using the following code:

String[] task = new String[] { "su", "settings put global airplane_mode_on 1", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true" };
try {
  Process process = Runtime.getRuntime().exec(task);
  process.waitFor();
} catch (IOException e) {

}catch (SecurityException e){

}catch (Exception e) {

}

This works correctly for rooted Meizu 5 (Android 6.0).
But it doesn't work for rooted Samsung S4 (Android 5.0.1) and Alcatel 5033D (Android 8.1.0) :(

When I used adb commands connecting phone to computer it worked correctly for Samsung:

adb shell settings put global airplane_mode_on 1
adb shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true

In some publics I saw advice in dividing the execution of a line in two stages:

"settings put global airplane_mode_on 1; am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true" };

"settings put global airplane_mode_on 1 && am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true"
But it did not help.

Tried another way:

String[][] t = new String[][]{new String[] { "su", "settings put global airplane_mode_on 1"},new String[] {"su","am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true" }};
//String[][] t = new String[][]{new String[] { "su", "settings put global airplane_mode_on 1"},new String[] {"am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true" }};
 try {
  Process process = null;
  for (String[] s : t) {
    process  = Runtime.getRuntime().exec(s);
  }
  process.waitFor();
}catch (IOException e) {
}catch (SecurityException e){
}catch (Exception e) {
}

But it also did not bring a positive result.


问:
PHPUnit and mocking objects in the require_once files
I am having trouble testing certain template parts in WordPress. WordPress template parts are essentially PHP files that are simply included with require/include when you dig deep enough.

This should be covered by end-to-end tests, but because sometimes these template parts contain some logic, I'd like to do some basic unit testing. These templates create instances of various classes and use them to generate output. So for testing purposes I wanted to mock those classes, however my mocked classes are constantly ignored and templates will always call original classes.

I suspect that there are some namespace shenanigans going on, but I really can't figure out where and how.

I made this little test to reproduce this behaviour.

Class method that needs to be mocked in the test:

```<code>namespace FooLib;

class NeedsMock {
    public function getStuff() {
        return "I have returned.";
    }
}
</code>```

Main file that creates an instance of the above class and calls a method from it:

```<code>require_once "./vendor/autoload.php";

use \FooLib\NeedsMock;

$stuff = new NeedsMock();
$result = $stuff->getStuff();

echo "I'm a little teapot.\n";
echo "Result: " . $result . "\n";
</code>```

And the test class which tests what main.php is outputting:

```<code>use PHPUnit\Framework\TestCase;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;

use FooLib\NeedsMock;

class MainTest extends TestCase {
    use MockeryPHPUnitIntegration;

    public function test_main() {
        $mock = \Mockery::mock(NeedsMock::class);
        $mock->shouldReceive('getStuff')->andReturn('Wherever you go, there you are.');

        ob_start();
        require_once "main.php";
        $res = ob_get_clean();
        $this->assertStringContainsString("Wherever you go, there you are.", $res, "It's good.");
    }
}
</code>```

First I create a mock of NeedsMock and mock the output of getStuff() then I capture the output of main and compare the expected result. Test fails because in main.php creates an instance of NeedsMock and doesn't use the mocked object.

I am aware that this is not the correct approach for testing things like this, but at the moment this is something I have to work with, so I'd like to cover a few things while we're in the process of refactoring everything and before end-to-end tests are written.

Is it possible to mock classes so that file included in the test will use those mocks?

Body:
I am having trouble testing certain template parts in WordPress. WordPress template parts are essentially PHP files that are simply included with require/include when you dig deep enough.

This should be covered by end-to-end tests, but because sometimes these template parts contain some logic, I'd like to do some basic unit testing. These templates create instances of various classes and use them to generate output. So for testing purposes I wanted to mock those classes, however my mocked classes are constantly ignored and templates will always call original classes.

I suspect that there are some namespace shenanigans going on, but I really can't figure out where and how.

I made this little test to reproduce this behaviour.

Class method that needs to be mocked in the test:

namespace FooLib;

class NeedsMock {
    public function getStuff() {
        return "I have returned.";
    }
}

Main file that creates an instance of the above class and calls a method from it:

require_once "./vendor/autoload.php";

use \FooLib\NeedsMock;

$stuff = new NeedsMock();
$result = $stuff->getStuff();

echo "I'm a little teapot.\n";
echo "Result: " . $result . "\n";

And the test class which tests what main.php is outputting:

use PHPUnit\Framework\TestCase;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;

use FooLib\NeedsMock;

class MainTest extends TestCase {
    use MockeryPHPUnitIntegration;

    public function test_main() {
        $mock = \Mockery::mock(NeedsMock::class);
        $mock->shouldReceive('getStuff')->andReturn('Wherever you go, there you are.');

        ob_start();
        require_once "main.php";
        $res = ob_get_clean();
        $this->assertStringContainsString("Wherever you go, there you are.", $res, "It's good.");
    }
}

First I create a mock of NeedsMock and mock the output of getStuff() then I capture the output of main and compare the expected result. Test fails because in main.php creates an instance of NeedsMock and doesn't use the mocked object.

I am aware that this is not the correct approach for testing things like this, but at the moment this is something I have to work with, so I'd like to cover a few things while we're in the process of refactoring everything and before end-to-end tests are written.

Is it possible to mock classes so that file included in the test will use those mocks?