SSHD: Get content of readonly-file - java

On my remote server I have a file which is read-only.
$ echo "Hello World" > /tmp/dummyfile && chmod a-w,a-x /tmp/dummyfile && ls -l /tmp/dummyfile
-r--r--r-- 1 dummyuser users 12 Mär 12 12:12 /tmp/dummyfile
I want to access my remote server via Java NIO API using Apache Mina SSHD like this:
SftpFileSystemProvider provider = new SftpFileSystemProvider(sshClient);
try (FileSystem fileSystem = provider.newFileSystem(uri, Collections.emptyMap())) {
Path path = fileSystem.getPath("/tmp/dummyfile");
byte[] bytes = Files.readAllBytes(path);
// ...
}
When I try to read a readonly-file (like the one above) I get an exception.
Exception in thread "main" SFTP error (SSH_FX_PERMISSION_DENIED): Permission denied
at org.apache.sshd.client.subsystem.sftp.impl.AbstractSftpClient.throwStatusException(AbstractSftpClient.java:210)
at org.apache.sshd.client.subsystem.sftp.impl.AbstractSftpClient.checkHandleResponse(AbstractSftpClient.java:245)
at org.apache.sshd.client.subsystem.sftp.impl.AbstractSftpClient.checkHandle(AbstractSftpClient.java:225)
at org.apache.sshd.client.subsystem.sftp.impl.AbstractSftpClient.open(AbstractSftpClient.java:665)
at org.apache.sshd.client.subsystem.sftp.SftpFileSystem$Wrapper.open(SftpFileSystem.java:284)
at org.apache.sshd.client.subsystem.sftp.SftpRemotePathChannel.<init>(SftpRemotePathChannel.java:77)
at org.apache.sshd.client.subsystem.sftp.SftpFileSystemChannel.<init>(SftpFileSystemChannel.java:35)
at org.apache.sshd.client.subsystem.sftp.SftpFileSystemChannel.<init>(SftpFileSystemChannel.java:31)
at org.apache.sshd.client.subsystem.sftp.SftpFileSystemProvider.newFileChannel(SftpFileSystemProvider.java:423)
at org.apache.sshd.client.subsystem.sftp.SftpFileSystemProvider.newByteChannel(SftpFileSystemProvider.java:413)
at org.apache.sshd.client.subsystem.sftp.SftpFileSystemProvider.newByteChannel(SftpFileSystemProvider.java:95)
at java.nio.file.Files.newByteChannel(Files.java:361)
at java.nio.file.Files.newByteChannel(Files.java:407)
at java.nio.file.Files.readAllBytes(Files.java:3152)
at test.Main.main(Main.java:36)
The exception is thrown because SftpFileSystemProvider.newFileChannel opens to file with read and write permission (see SftpFileSystemProvider.java:420), but the user doesn't have the write permission.
How can I read the file content of my readonly-file with Java NIO and Apache Mina SSHD?

Related

How can I get notified when money has been sent to a particular Bitcoin address on a local regtest network?

I want to programmatically detect whenever someone sends Bitcoin to some address. This happens on a local testnet which I start using this docker-compose.yml file.
Once the local testnet runs, I create a new address using
docker exec -it minimal-crypto-exchange_node_1 bitcoin-cli getnewaddress
Let's say it returns 2N23tWAFEtBtTgxNjBNmnwzsiPdLcNek181.
I put this address into the following Java code:
import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.wallet.Wallet;
import org.bitcoinj.wallet.listeners.WalletCoinsReceivedEventListener;
public class WalletObserver {
public void init() {
final NetworkParameters netParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST);
try {
final Wallet wallet = Wallet.createBasic(netParams);
wallet.addWatchedAddress(Address.fromString(netParams, "2N23tWAFEtBtTgxNjBNmnwzsiPdLcNek181"));
wallet.addCoinsReceivedEventListener(new WalletCoinsReceivedEventListener() {
#Override
public void onCoinsReceived(final Wallet wallet, final Transaction transaction, final Coin prevBalance, final Coin newBalance) {
System.out.println("Heyo!");
}
});
}
catch (Exception exception) {
exception.printStackTrace();
}
}
}
Then I start the Java application with this class.
Then I send some test Bitcoin to the address in question:
% docker exec -it minimal-crypto-exchange_node_1 bitcoin-cli sendtoaddress 2N23tWAFEtBtTgxNjBNmnwzsiPdLcNek181 0.5
068c377bab961356ad9a3919229a764aa929711c68aefd5dbd4c7c348eef3406
If I go to http://localhost:3002/tx/068c377bab961356ad9a3919229a764aa929711c68aefd5dbd4c7c348eef3406, I see that the transaction details.
However, the breakpoint in the listener (onCoinsReceived method) never activates.
How do I need to modify my code and/or the commands I use to send test BTC so that whenever money is received by that account, onCoinsReceived method is called? Is there a place where I can tell Wallet or NetworkParameters that I want to connect to localhost?
I am using version 0.15.10 of bitcoinj-core.
Update 1:
I modified docker-compose.yml and added following port mappings:
ports:
- "51001:50001"
- "51002:50002"
- "19001:19001"
- "19000:19000"
- "28332:28332"
Then I rewrote the init method so that I can connect to localhost and specify the port:
public class WalletObserver {
public void init() {
final LocalTestNetParams netParams = new LocalTestNetParams();
netParams.setPort(50001);
try {
final WalletAppKit kit = new WalletAppKit(netParams, new File("."), "_minimalCryptoExchangeBtcWallet");
kit.setAutoSave(true);
kit.connectToLocalHost();
kit.startAsync();
kit.awaitRunning(); // I never get past this point
kit.peerGroup().addPeerDiscovery(new DnsDiscovery(netParams));
kit.wallet().addWatchedAddress(Address.fromString(netParams, "2N23tWAFEtBtTgxNjBNmnwzsiPdLcNek181"));
kit.wallet().addCoinsReceivedEventListener(new WalletCoinsReceivedEventListener() {
#Override
public void onCoinsReceived(final Wallet wallet, final Transaction transaction, final Coin prevBalance, final Coin newBalance) {
System.out.println("Heyo!");
}
});
}
catch (Exception exception) {
exception.printStackTrace();
}
}
LocalTestNetParams allows to specify the port:
package com.dpisarenko.minimalcryptoexchange.logic.btc;
import org.bitcoinj.params.RegTestParams;
public class LocalTestNetParams extends RegTestParams {
public void setPort(final int newPort) {
this.port = newPort;
}
}
I tried all of the aforementioned ports in netParams.setPort(50001);.
In all cases I get the following messages after kit.awaitRunning();:
22:16:34.245 [PeerGroup Thread] INFO org.bitcoinj.core.PeerGroup - Attempting connection to [10.10.1.218]:50001 (0 connected, 1 pending, 1 max)
22:16:34.265 [NioClientManager] WARN org.bitcoinj.net.NioClientManager - Failed to connect with exception: java.net.ConnectException: Connection refused
java.net.ConnectException: Connection refused
at java.base/sun.nio.ch.Net.pollConnect(Native Method)
at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:579)
at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:820)
at org.bitcoinj.net.NioClientManager.handleKey(NioClientManager.java:64)
at org.bitcoinj.net.NioClientManager.run(NioClientManager.java:122)
at com.google.common.util.concurrent.AbstractExecutionThreadService$1$2.run(AbstractExecutionThreadService.java:66)
at com.google.common.util.concurrent.Callables$4.run(Callables.java:119)
at org.bitcoinj.utils.ContextPropagatingThreadFactory$1.run(ContextPropagatingThreadFactory.java:51)
at java.base/java.lang.Thread.run(Thread.java:830)
22:16:34.267 [NioClientManager] INFO org.bitcoinj.core.PeerGroup - [10.10.1.218]:50001: Peer died (0 connected, 0 pending, 1 max)
22:16:34.267 [PeerGroup Thread] INFO org.bitcoinj.core.PeerGroup - Peer discovery took 21.84 μs and returned 0 items from 0 discoverers
22:16:34.269 [PeerGroup Thread] INFO org.bitcoinj.core.PeerGroup - Waiting 1502 ms before next connect attempt to [10.10.1.218]:50001
22:16:35.776 [PeerGroup Thread] INFO org.bitcoinj.core.PeerGroup - Attempting connection to [10.10.1.218]:50001 (0 connected, 1 pending, 1 max)
22:16:35.778 [NioClientManager] WARN org.bitcoinj.net.NioClientManager - Failed to connect with exception: java.net.ConnectException: Connection refused
java.net.ConnectException: Connection refused
at java.base/sun.nio.ch.Net.pollConnect(Native Method)
at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:579)
at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:820)
at org.bitcoinj.net.NioClientManager.handleKey(NioClientManager.java:64)
at org.bitcoinj.net.NioClientManager.run(NioClientManager.java:122)
at com.google.common.util.concurrent.AbstractExecutionThreadService$1$2.run(AbstractExecutionThreadService.java:66)
at com.google.common.util.concurrent.Callables$4.run(Callables.java:119)
at org.bitcoinj.utils.ContextPropagatingThreadFactory$1.run(ContextPropagatingThreadFactory.java:51)
at java.base/java.lang.Thread.run(Thread.java:830)
22:16:35.778 [NioClientManager] INFO org.bitcoinj.core.PeerGroup - [10.10.1.218]:50001: Peer died (0 connected, 0 pending, 1 max)
22:16:35.779 [PeerGroup Thread] INFO org.bitcoinj.core.PeerGroup - Peer discovery took 8.752 μs and returned 0 items from 0 discoverers
10.10.1.218 seems to be generated by InetAddress.getLocalHost() in org.bitcoinj.kits.WalletAppKit#connectToLocalHost:
public WalletAppKit connectToLocalHost() {
try {
InetAddress localHost = InetAddress.getLocalHost();
return this.setPeerNodes(new PeerAddress(this.params, localHost, this.params.getPort()));
} catch (UnknownHostException var2) {
throw new RuntimeException(var2);
}
}
Update 1:
I tried to use network_mode: "host".
If I add it to node as in
node:
image: ulamlabs/bitcoind-custom-regtest:latest
network_mode: "host"
I get the following error when I run docker-compose up -d:
minimal-crypto-exchange % docker-compose up -d
Creating network "minimal-crypto-exchange_default" with the default driver
Creating minimal-crypto-exchange_postgres_1 ... done
Creating minimal-crypto-exchange_geth_1 ...
Creating minimal-crypto-exchange_node_1 ... done
Creating minimal-crypto-exchange_electrumx_1 ...
Creating minimal-crypto-exchange_electrumx_1 ... error
ERROR: for minimal-crypto-exchange_electrumx_1 Cannot start service electrumx: driver fail
Creating minimal-crypto-exchange_geth_1 ... done
f68d0f25a0512399877bc55434513def810649e4fcf31a5a88ca3292d34): Error starting userland proxy: listen tcp4 0.0.0.0:28332: bind: address already in use
Creating minimal-crypto-exchange_blockscout_1 ... done
ERROR: for electrumx Cannot start service electrumx: driver failed programming external connectivity on endpoint minimal-crypto-exchange_electrumx_1 (8eaa4f68d0f25a0512399877bc55434513def810649e4fcf31a5a88ca3292d34): Error starting userland proxy: listen tcp4 0.0.0.0:28332: bind: address already in use
ERROR: Encountered errors while bringing up the project.
If I add it to electrumx part as in
electrumx:
image: lukechilds/electrumx:latest
network_mode: "host"
I get another error:
minimal-crypto-exchange % docker-compose up -d
minimal-crypto-exchange_postgres_1 is up-to-date
minimal-crypto-exchange_geth_1 is up-to-date
Recreating minimal-crypto-exchange_node_1 ...
Recreating minimal-crypto-exchange_node_1 ... done
Recreating minimal-crypto-exchange_electrumx_1 ...
ERROR: for minimal-crypto-exchange_electrumx_1 "host" network_mode is incompatible with port_bindings
ERROR: for electrumx "host" network_mode is incompatible with port_bindings
Traceback (most recent call last):
File "docker-compose", line 3, in <module>
File "compose/cli/main.py", line 81, in main
File "compose/cli/main.py", line 203, in perform_command
File "compose/metrics/decorator.py", line 18, in wrapper
File "compose/cli/main.py", line 1186, in up
File "compose/cli/main.py", line 1166, in up
File "compose/project.py", line 697, in up
File "compose/parallel.py", line 108, in parallel_execute
File "compose/parallel.py", line 206, in producer
File "compose/project.py", line 679, in do
File "compose/service.py", line 579, in execute_convergence_plan
File "compose/service.py", line 499, in _execute_convergence_recreate
File "compose/parallel.py", line 108, in parallel_execute
File "compose/parallel.py", line 206, in producer
File "compose/service.py", line 494, in recreate
File "compose/service.py", line 612, in recreate_container
File "compose/service.py", line 330, in create_container
File "compose/service.py", line 939, in _get_container_create_options
File "compose/service.py", line 1014, in _get_container_host_config
File "docker/api/container.py", line 598, in create_host_config
File "docker/types/containers.py", line 338, in __init__
docker.errors.InvalidArgument: "host" network_mode is incompatible with port_bindings
[44262] Failed to execute script docker-compose
Update 2:
If I comment out port bindings as in
electrumx:
image: lukechilds/electrumx:latest
network_mode: host
links:
- node
# Port settings see https://github.com/ulamlabs/bitcoind-custom-regtest
# ports:
# - "51001:50001"
# - "51002:50002"
# - "19001:19001"
# - "19000:19000"
# - "28332:28332"
and run docker-compose up -d I get
% docker-compose up -d
Creating network "minimal-crypto-exchange_default" with the default driver
Creating minimal-crypto-exchange_geth_1 ...
Creating minimal-crypto-exchange_postgres_1 ... done
Creating minimal-crypto-exchange_node_1 ... done
Creating minimal-crypto-exchange_electrumx_1 ... error
Creating minimal-crypto-exchange_geth_1 ... done
ERROR: for minimal-crypto-exchange_electrumx_1 Cannot create container for service electrumx: conflicting options: host type networking can't be used with links. This would result in undefined behavior
Creating minimal-crypto-exchange_blockscout_1 ... done
ERROR: for electrumx Cannot create container for service electrumx: conflicting options: host type networking can't be used with links. This would result in undefined behavior
ERROR: Encountered errors while bringing up the project.
Update 3: I assume that the root of the error is that in my Java code I try to connect to the ElectrumX server instead of the actual Bitcoin node (node in docker-compose.yml).
Update 4:
I changed docker-compose.yml as follows:
node:
image: ulamlabs/bitcoind-custom-regtest:latest
# For ports used by node see
# https://github.com/ulamlabs/bitcoind-custom-regtest/blob/master/bitcoin.conf
ports:
- "19001:19001"
- "19000:19000"
- "28332:28332"
electrumx:
image: lukechilds/electrumx:latest
links:
- node
# Port settings see https://github.com/ulamlabs/bitcoind-custom-regtest
ports:
- "51001:50001"
- "51002:50002"
# - "19001:19001"
# - "19000:19000"
# - "28332:28332"
Now I am getting different errors (full log available here):
11:33:51.865 [NioClientManager] INFO org.bitcoinj.core.PeerGroup - [192.168.10.208]:19000: Peer died (0 connected, 0 pending, 1 max)
11:33:51.865 [NioClientManager] INFO org.bitcoinj.core.PeerGroup - Not yet setting download peer because there is no clear candidate.
11:33:51.865 [NioClientManager] DEBUG org.bitcoinj.core.BitcoinSerializer - Received 168 byte 'alert' message: 60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50
11:33:51.866 [PeerGroup Thread] INFO org.bitcoinj.core.PeerGroup - Waiting 999 ms before next connect attempt to [127.0.0.1]:19000
11:33:51.866 [NioClientManager] DEBUG org.bitcoinj.core.Peer - Received alert from peer Peer{[192.168.10.208]:19000, version=70015, subVer=/Satoshi:0.19.1(bitcore)/, services=1033 (NETWORK, WITNESS, NETWORK_LIMITED), time=2021-11-06 11:33:52, height=5}: URGENT: Alert key compromised, upgrade required
11:33:51.867 [NioClientManager] WARN org.bitcoinj.net.ConnectionHandler - Error handling SelectionKey: java.nio.channels.CancelledKeyException
java.nio.channels.CancelledKeyException: null
at java.base/sun.nio.ch.SelectionKeyImpl.ensureValid(SelectionKeyImpl.java:71)
at java.base/sun.nio.ch.SelectionKeyImpl.readyOps(SelectionKeyImpl.java:130)
at java.base/java.nio.channels.SelectionKey.isWritable(SelectionKey.java:377)
at org.bitcoinj.net.ConnectionHandler.handleKey(ConnectionHandler.java:244)
at org.bitcoinj.net.NioClientManager.handleKey(NioClientManager.java:86)
at org.bitcoinj.net.NioClientManager.run(NioClientManager.java:122)
at com.google.common.util.concurrent.AbstractExecutionThreadService$1$2.run(AbstractExecutionThreadService.java:66)
at com.google.common.util.concurrent.Callables$4.run(Callables.java:119)
at org.bitcoinj.utils.ContextPropagatingThreadFactory$1.run(ContextPropagatingThreadFactory.java:51)
at java.base/java.lang.Thread.run(Thread.java:830)
Update 5:
Someone suggested (in a now removed comment) that in the output of the application there is this Peer does not support bloom filtering message:
11:32:43.482 [NioClientManager] INFO org.bitcoinj.core.Peer - Peer{[127.0.0.1]:19000, version=70015, subVer=/Satoshi:0.19.1(bitcore)/, services=1033 (NETWORK, WITNESS, NETWORK_LIMITED), time=2021-11-06 11:32:43, height=4}: Peer does not support bloom filtering.
So I tried to fork the original image and change the bitcoin.conf file to enable Bloom filtering:
peerbloomfilters=1
When I run docker build -t mentiflectax/bitcoind-custom-regtest:latest . I get the following error message (part of remaining output can be found here):
#13 922.4 g++: fatal error: Killed signal terminated program cc1plus
#13 922.4 compilation terminated.
#13 922.4 make[2]: *** [Makefile:8044: libbitcoin_server_a-init.o] Error 1
#13 922.4 make[2]: *** Waiting for unfinished jobs....
#13 965.8 make[2]: Leaving directory '/bitcoin-0.19.1/src'
#13 965.8 make[1]: *** [Makefile:13765: all-recursive] Error 1
#13 965.9 make[1]: Leaving directory '/bitcoin-0.19.1/src'
#13 965.9 make: *** [Makefile:776: all-recursive] Error 1
------
executor failed running [/bin/sh -c tar -xzf *.tar.gz && cd bitcoin-${BITCOIN_VERSION} && sed -i 's/consensus.nSubsidyHalvingInterval = 150/consensus.nSubsidyHalvingInterval = 210000/g' src/chainparams.cpp && ./autogen.sh && ./configure LDFLAGS=-L`ls -d /opt/db`/lib/ CPPFLAGS=-I`ls -d /opt/db`/include/ --prefix=/opt/bitcoin --disable-man --disable-tests --disable-bench --disable-ccache --with-gui=no --enable-util-cli --with-daemon && make -j4 && make install && strip /opt/bitcoin/bin/bitcoin-cli && strip /opt/bitcoin/bin/bitcoind]: exit code: 2
Update 6: The correct port seems to be 19000.
If I use port 19001, I get following errors after kit.awaitRunning():
INFO org.bitcoinj.core.PeerSocketHandler - [127.0.0.1]:19001: Timed out
Full log output is available here.
I haven't tested your full setup with electrumx and the ethereum stuff present in your docker-compose file, but regarding your problem, the following steps worked properly, and I think it will do as well in your complete setup.
I ran with docker a bitcoin node based in the ulamlabs/bitcoind-custom-regtest:latest image you provided:
docker run -p 18444:19000 -d ulamlabs/bitcoind-custom-regtest:latest
As you can see, I exposed the image internal port 19000 as the default port for RegTestParams, 18444. From the point of view of our client, with this setup, basically it will look like as if we were running the bitcoin daemon in the host. Using your LocalTestNetParams class and providing the port 19000 as you indicated should do the trick as well.
Then, according to the feedback you provided in the question, I manually edited the daemon configuration of the bitcoin node in /root/.bitcoin/bitcoin.conf using bash and vi:
docker exec -it 0aa2e863cd9927 bash
And included the following configuration:
peerbloomfilters=1
After restart the container, I got a new address:
docker exec -it 0aa2e863cd9927 bitcoin-cli -regtest getnewaddress
Let's assume that the new address is the one you provided in the question:
2N23tWAFEtBtTgxNjBNmnwzsiPdLcNek181
Then, as suggested in the Bitcoin documentation, in order to avoid an insufficient funds error, I generated 101 blocks to this address:
docker exec -it 0aa2e863cd9927 bitcoin-cli -regtest generatetoaddress 101 2N23tWAFEtBtTgxNjBNmnwzsiPdLcNek181
I used generatetoaddress and not generate because since Bitcoin 0.19.0 the option is no longer valid.
Next, I prepared a simple Java program, based in the information you provided and this example from the Bitcoinj library documentation:
import java.io.File;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.params.RegTestParams;
public class Kit {
public static void main(String[] args) {
Kit kit = new Kit();
kit.run();
}
private synchronized void run(){
NetworkParameters params = RegTestParams.get();
WalletAppKit kit = new WalletAppKit(params, new File("."), "walletappkit-example");
kit.connectToLocalHost();
kit.startAsync();
kit.awaitRunning();
kit.wallet().addWatchedAddress(Address.fromString(params, "2N23tWAFEtBtTgxNjBNmnwzsiPdLcNek181"));
kit.wallet().addCoinsReceivedEventListener((wallet, tx, prevBalance, newBalance) -> {
System.out.println("-----> coins resceived: " + tx.getTxId());
});
while (true) {
try {
this.wait(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I used a simple while loop to keep the problem running; of course, if will be probably unnecessary in an actual setup as it seems you are using Spring Boot.
Then, if you send some bitcoins to this address:
docker exec -it 0aa2e863cd9927 bitcoin-cli -regtest sendtoaddress 2N23tWAFEtBtTgxNjBNmnwzsiPdLcNek181 0.00001
0f972642713c72ae0fe03fe51818b9ea4d483720b69b90e795f35eb80a587c26
The listener should be invoked:
2021-11-09 23:51:20.537 INFO [NioClientManager][Wallet] Received a pending transaction 0f972642713c72ae0fe03fe51818b9ea4d483720b69b90e795f35eb80a587c26 that spends 0.00 BTC from our own wallet, and sends us 0.00001 BTC
2021-11-09 23:51:20.537 INFO [NioClientManager][Wallet] commitTx of 0f972642713c72ae0fe03fe51818b9ea4d483720b69b90e795f35eb80a587c26
...
2021-11-09 23:51:20.537 INFO [NioClientManager][Wallet] ->pending: 0f972642713c72ae0fe03fe51818b9ea4d483720b69b90e795f35eb80a587c26
2021-11-09 23:51:20.537 INFO [NioClientManager][Wallet] Estimated balance is now: 0.00001 BTC
-----> coins resceived: 0f972642713c72ae0fe03fe51818b9ea4d483720b69b90e795f35eb80a587c26
2021-11-09 23:51:20.538 INFO [NioClientManager][WalletFiles] Saving wallet; last seen block is height 165, date 2021-11-09T22:50:48Z, hash 23451521947bc5ff098c088ae0fc445becca8837d39ee8f6dd88f2c47ad5ac23
2021-11-09 23:51:20.543 INFO [NioClientManager][WalletFiles] Save completed in 4.736 ms
There is still a problem you mentioned that I haven't had the opportunity to test, and it is creating a new Docker image in which the peerbloomfilters configuration would be configured properly without modifying the actual container state. I think the compilation problem you indicated could be related to this issue, basically, that the container didn't have enough resources to perform the process. If you are using macOS and Docker for Mac, try tweaking the amount of memory available to your containers, it may be of help. A change in the base alpine image used can motivate the problem also. I will try digging into the issue as well.

Pyspark throws Java gateway exception if I open a file before getting a SparkContext()

I am using pyspark on Jupyter Notebook with Spark 2.1.1 cluster running on IP "spark://remote:port" (spark master IP)
I am able to create a SparkContext successfully.
But, I want to read spark_master_ip and spark.cores.max from a .properties file (instead of hard coding it). When I try to read my custom spark properties file in 'myspark_config.properties' file (which I parse and read successfully), but I get the following Java gateway exception, when I try to create SparkContext().
Here is my code:
import pyspark
from pprint import pprint
from pyspark import SparkConf
def getproperties():
"""Get Spark configuration properties in python dictionary"""
global properties
properties = dict()
with open('myspark_config.properties') as f:
for line in f:
if not line.startswith('#') and not line.startswith('\n'):
tokens = line.split('=')
tokens[0] = tokens[0].strip()
tokens[1] = "=".join(tokens[1:])
properties[tokens[0]] = tokens[1].strip()
f.close()
pprint(properties)
return(properties)
properties = getproperties()
conf = (SparkConf()
.setMaster(properties["spark_master_url"])
.setAppName("testApp")
.set('spark.cores.max',properties["spark_app_cores"])
.set('spark.executor.memory',properties["spark_app_memory"])
.set('spark.dynamicAllocation.enabled','true')
.set('spark.shuffle.service.enabled','true')
)
# conf = (SparkConf()
# .setMaster("spark://remote:port")
# .setAppName("testApp")
# .set('spark.cores.max',"2")
# .set('spark.executor.memory',"2G")
# .set('spark.dynamicAllocation.enabled','true')
# .set('spark.shuffle.service.enabled','true')
# )
sc = pyspark.SparkContext(conf=conf)
I do not get any exceptions and my code runs smoothly if I don't read from file and hard code the spark master in SparkConf() (currently it is commented). "JAVA_HOME","SPARK_HOME" "PYTHONPATH" are set successfully and I am not using Anaconda. I am using Jupyter notebook on python 2.7 on ubuntu and spark-2.1.1
{'spark_app_cores': '"2"',
'spark_app_memory': '"2G"',
'spark_master_url': '"spark://remote:port"'}
Exception Traceback (most recent call last)
<ipython-input-1-c893eaf079f2> in <module>()
36 # .set('spark.shuffle.service.enabled','true')
37 # )
---> 38 sc = pyspark.SparkContext(conf=conf)
/usr/local/spark/python/pyspark/context.py in __init__(self, master, appName, sparkHome, pyFiles, environment, batchSize, serializer, conf, gateway, jsc, profiler_cls)
113 """
114 self._callsite = first_spark_call() or CallSite(None, None, None)
--> 115 SparkContext._ensure_initialized(self, gateway=gateway, conf=conf)
116 try:
117 self._do_init(master, appName, sparkHome, pyFiles, environment, batchSize, serializer,
/usr/local/spark/python/pyspark/context.py in _ensure_initialized(cls, instance, gateway, conf)
281 with SparkContext._lock:
282 if not SparkContext._gateway:
--> 283 SparkContext._gateway = gateway or launch_gateway(conf)
284 SparkContext._jvm = SparkContext._gateway.jvm
285
/usr/local/spark/python/pyspark/java_gateway.py in launch_gateway(conf)
93 callback_socket.close()
94 if gateway_port is None:
---> 95 raise Exception("Java gateway process exited before sending the driver its port number")
96
97 # In Windows, ensure the Java child processes do not linger after Python has exited.
Exception: Java gateway process exited before sending the driver its port number
I have looked through various links but found no solution:
pyspark java gateway error stackoverflow
Github issue on java Gateway
But, I want to read spark_master_ip and spark.cores.max from a .properties file (instead of hard coding it).
That is awesome idea, but you're ignoring the fact, that this is what $SPARK_HOME/conf/spark-defaults.conf is for. Just put required properties there.
but I get the following Java gateway exception,
This looks wrong:
"=".join(tokens[1:])
Why would use = in properties?
Otherwise it should have no effect. Also Python provides property parser https://docs.python.org/3/library/configparser.html

FileHandler causing IOException at FileKey

I call a java class from PLSQL Dev. My Logger.java calls the FileHandler with a string "C:\Logs\mylog.TXT"
fileHndlr = new FileHandler(logFileName, false);
and the result is:
Exception in thread "Root Thread" java.lang.Error: java.io.IOException: sjonfile_fileinfo fais to get fileinfo
at sun.nio.ch.FileKey.create(FileKey.java:41)
at sun.nio.ch.FileChannelImpl$SharedFileLockTable.<init>(FileChannelImpl.java:1037)
at sun.nio.ch.FileChannelImpl.fileLockTable(FileChannelImpl.java:806)
at sun.nio.ch.FileChannelImpl.tryLock(FileChannelImpl.java:867)
at java.nio.channels.FileChannel.tryLock(FileChannel.java:962)
at java.util.logging.FileHandler.openFiles(FileHandler.java:394)
at java.util.logging.FileHandler.<init>(FileHandler.java:268)
at xxx.logger.Logger.logSetup(Logger.java:194)
Caused by: java.io.IOException: sjonfile_fileinfo fais to get fileinfo
at sun.nio.ch.FileKey.init(Native Method)
at sun.nio.ch.FileKey.create(FileKey.java:39)
... 9 more
Seems some rights is missing to create the file, what need to be checked?
UPDATE:
we installed the processmonitor to the server where the file operations happening and we found two suspicious events:
1) BUFFER OVERFLOW error at QueryAllInformationFile
Date & Time: 2015.03.02. 9:23:14
Event Class: File System
Operation: QueryAllInformationFile
Result: BUFFER OVERFLOW
Path: C:\Logs\...\filename.lck
TID: 2708
Duration: 0.0000138
CreationTime: 2015.02.25. 15:49:13
LastAccessTime: 2015.02.25. 15:49:13
LastWriteTime: 2015.03.02. 9:23:14
ChangeTime: 2015.03.02. 9:23:14
FileAttributes: A
AllocationSize: 0
EndOfFile: 0
NumberOfLinks: 1
DeletePending: False
Directory: False
IndexNumber: 0x1500000007d793
EaSize: 0
Access: Generic Write, Read Attributes
Position: 0
Mode: Synchronous IO Non-Alert
AlignmentRequirement: Long
2) SHARING VIOLATION error at CreateFile operation
Date & Time: 2015.03.02. 9:23:20
Event Class: File System
Operation: CreateFile
Result: SHARING VIOLATION
Path: C:\Logs\...\filename.lck
TID: 2708
Duration: 0.0000284
Desired Access: Read Attributes, Delete
Disposition: Open
Options: Non-Directory File, Open Reparse Point
Attributes: n/a
ShareMode: Read, Write, Delete
AllocationSize: n/a
following actions need to be executed with sysdba user:
GRANT READ,WRITE ON DIRECTORY userDirectory TO userSchema;
Execute dbms_java.grant_permission('userSchema', 'java.io.FilePermission', 'userDirectory/*', 'read,write,execute,delete');

Xpages runtime error: 'java class java.lang.IllegalStateException: Access denied (java.lang.RuntimePermission getClassLoader)'

I am trying to call 'new XWPFDocument(inStream);' in a java class in an XPages application. The XWPFDocument class is part of the Apache POI library. However when it gets to the call to this constructor at runtime, I get the following stack trace:
11/02/2014 20:57:02 HTTP JVM: java.lang.IllegalStateException: Access denied (java.lang.RuntimePermission getClassLoader)
11/02/2014 20:57:02 HTTP JVM: at org.apache.xmlbeans.XmlBeans.getContextTypeLoader(XmlBeans.java:336)
11/02/2014 20:57:02 HTTP JVM: at org.openxmlformats.schemas.wordprocessingml.x2006.main.DocumentDocument$Factory.parse(Unknown Source)
11/02/2014 20:57:02 HTTP JVM: at org.apache.poi.xwpf.usermodel.XWPFDocument.onDocumentRead(XWPFDocument.java:134)
11/02/2014 20:57:02 HTTP JVM: at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:159) ...
I have added all the necessary jar files to the 'Web Content/WEB INF/lib' folder under package explorer, and subsequently added them to the project's java build path. Am I missing something?
The code around the call is:
OutputStream outStream = response.getOutputStream();
InputStream inStream = null;
EmbeddedObject embeddedObj = null;
XWPFDocument document = null;
if (attachments.size() > 0) {
String attachmentName = attachments.get(0).toString();
embeddedObj = downloadDocument.getAttachment(attachmentName);
if (embeddedObj != null) {
inStream = embeddedObj.getInputStream();
document = new XWPFDocument(inStream);
inStream.close();
document.write(outStream);
}
}
Add to Domino server's jvm/lib/security/java.policy file
grant codeBase "xspnsf://server:0/<application>.nsf/WEB-INF/lib/*" {
permission java.lang.RuntimePermission "getClassLoader";
}
or put the jar files into Domino server's trusted folder jvm/lib/ext.

Reading HDFS through java API

[possible duplicate]I am trying to read HDFS using java API. Using command line and Hadoop Url It's working fine
but problem is reading while hdfs paths.I went through this Reading HDFS and local files in Java but I am not able to find where i am wrong.
1)command line gives this result
hduser#hduser-Satellite:~$ hadoop fs -ls
Found 3 items
drwxr-xr-x - hduser supergroup 0 2014-01-11 00:21 /user/hduser/In
-rw-r--r-- 1 hduser supergroup 37461150 2014-01-11 17:27 /user/hduser/loging.txt
-rw-r--r-- 3 hduser supergroup 112383446 2014-01-11 19:02 /user/hduser/loging1.txt
2)
static {
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
}
InputStream in = null;
try {
*********************This is working fine********************************
in = new URL("hdfs://localhost:54310/user/hduser/loging.txt")
.openStream();
*************************************************************************
*************************This is not working*****************************
in = new URL("hdfs://localhost/user/hduser/loging.txt").openStream();
It says:
14/01/11 19:54:55 INFO ipc.Client: Retrying connect to server:
localhost/127.0.0.1:8020. Already tried 0 time(s).
.
.
14/01/11 19:55:04 INFO ipc.Client: Retrying connect to server:
localhost/127.0.0.1:8020. Already tried 9 time(s).
Exception in thread "main" java.net.ConnectException: Call to
localhost/127.0.0.1:8020 failed on connection exception: java.net.ConnectException: Connection refused
**************************************************************************
IOUtils.copyBytes(in, System.out, 4096, false);
} finally {
IOUtils.closeStream(in);
}
3)Giving Exception
Configuration configuration = new Configuration();
configuration.addResource(new Path("/hadoop/conf/core-site.xml"));
configuration.addResource(new Path("/hadoop/conf/hdfs-site.xml"));
FileSystem fileSystem = FileSystem.get(configuration);
System.out.println(fileSystem.getHomeDirectory());
Path path = new Path("/user/hduser/loging.txt");
FSDataInputStream in = fileSystem.open(path);
System.out.println(in);
byte[] b = new byte[1024];
int numBytes = 0;
while ((numBytes = in.read(b)) > 0) {
//processing
}
in.close();
fileSystem.close();
Exception:
file:/home/hduser
Exception in thread "main" java.io.FileNotFoundException: File /user/hduser/loging.txt does not exist.
at org.apache.hadoop.fs.RawLocalFileSystem.getFileStatus(RawLocalFileSystem.java:361)
at org.apache.hadoop.fs.FilterFileSystem.getFileStatus(FilterFileSystem.java:245)
at org.apache.hadoop.fs.ChecksumFileSystem$ChecksumFSInputChecker.<init>(ChecksumFileSystem.java:125)
at org.apache.hadoop.fs.ChecksumFileSystem.open(ChecksumFileSystem.java:283)
at org.apache.hadoop.fs.FileSystem.open(FileSystem.java:356)
at HdfsUrl.read(HdfsUrl.java:29)
at HdfsUrl.main(HdfsUrl.java:58)
The kind of exception you are getting suggests thats your application is trying to connect to a datanode that does not have 8020 port open. As per this documentation 8020 is the default port namenode. I'd suggest adding your hostname and port info. in your core-site.xml. something like this:
<property>
<name>fs.default.name</name>
<value>hdfs://[namenode]:[port]</value>
</property>

Categories