Skip to content

Commit 129f7e8

Browse files
skletsundmitry-timofeev
authored andcommitted
Fix cryptocurrency and QA scripts (#965)
Fixed these scripts (that allow to launch a non-packaged app through `cargo run`) by introducing an optional command line argument allowing to override java.library.path. If it is not specified — <executable location>/lib/native is used.
1 parent a00adba commit 129f7e8

9 files changed

Lines changed: 53 additions & 34 deletions

File tree

exonum-java-binding/core/rust/exonum-java/start_cryptocurrency_node.sh

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ echo "${SERVICE_NAME} = '${ARTIFACT_PATH}'" >> ${SERVICES_CONFIG_FILE}
4545
header "PREPARE PATHS"
4646

4747
EJB_LOG_CONFIG_PATH="${EJB_APP_DIR}/log4j-fallback.xml"
48-
49-
export LD_LIBRARY_PATH="$JAVA_LIB_DIR"
50-
echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"
48+
JAVA_LIBRARY_PATH="${EJB_ROOT}/core/rust/target/debug"
5149

5250
# Clear test dir
5351
rm -rf testnet
@@ -78,4 +76,5 @@ cargo +$RUST_COMPILER_VERSION run -- run -d testnet/db -c testnet/node.toml \
7876
--service-key-pass pass \
7977
--public-api-address 127.0.0.1:3000 \
8078
--ejb-log-config-path $EJB_LOG_CONFIG_PATH \
81-
--ejb-port 7000
79+
--ejb-port 7000 \
80+
--ejb-override-java-library-path $JAVA_LIBRARY_PATH

exonum-java-binding/core/rust/exonum-java/start_qa_node.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ echo "PROJ_ROOT=${EJB_ROOT}"
3232

3333
source "${EJB_ROOT}/tests_profile"
3434

35-
export LD_LIBRARY_PATH="${JAVA_LIB_DIR}"
36-
echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"
35+
java_library_path="${EJB_ROOT}/core/rust/target/debug"
3736

3837
# Find the artifact
3938
ARTIFACT_PATH="$(find ${EJB_ROOT} -type f -name exonum-java-binding-qa-service-*-artifact.jar)"
@@ -104,7 +103,8 @@ do
104103
--consensus-key-pass pass \
105104
--service-key-pass pass \
106105
--public-api-address 0.0.0.0:${port} \
107-
--private-api-address 0.0.0.0:${private_port} &
106+
--private-api-address 0.0.0.0:${private_port} \
107+
--ejb-override-java-library-path ${java_library_path} &
108108

109109
echo "new node with ports: $port (public) and $private_port (private)"
110110
done

exonum-java-binding/core/rust/integration_tests/src/vm.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,11 @@ pub fn log4j_path() -> String {
145145
}
146146

147147
fn libpath_option() -> String {
148-
format!("-Djava.library.path={}", libpath())
148+
format!("-Djava.library.path={}", java_library_path())
149149
}
150150

151-
fn libpath() -> String {
151+
/// Returns path to the java_bindings library for native integration tests.
152+
pub fn java_library_path() -> String {
152153
let library_path = rust_project_root_dir()
153154
.join(target_path())
154155
.canonicalize()

exonum-java-binding/core/rust/integration_tests/tests/service_factory_adapter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn test_callbacks() {
4343

4444
let run_command_ext = run_command_ext.unwrap();
4545
let arguments = run_command_ext.args();
46-
assert_eq!(arguments.len(), 5);
46+
assert_eq!(arguments.len(), 6);
4747

4848
// Make sure another instance of JavaServiceFactoryAdapter does not extend the `Run` command.
4949
let mut one_more_adapter =

exonum-java-binding/core/rust/integration_tests/tests/service_runtime_bootstrap.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
extern crate integration_tests;
1818
extern crate java_bindings;
1919

20-
use integration_tests::vm::{fakes_classpath, log4j_path};
20+
use integration_tests::vm::{fakes_classpath, java_library_path, log4j_path};
2121
use java_bindings::{Config, InternalConfig, JavaServiceRuntime, JvmConfig, RuntimeConfig};
2222

2323
#[test]
@@ -35,6 +35,7 @@ fn bootstrap() {
3535
// Pass log4j path to avoid error messages of mis-configuration
3636
log_config_path: log4j_path(),
3737
port: 6300,
38+
override_system_lib_path: None,
3839
};
3940

4041
let config = Config {
@@ -44,7 +45,7 @@ fn bootstrap() {
4445

4546
let internal_config = InternalConfig {
4647
system_class_path: fakes_classpath(),
47-
system_lib_path: None,
48+
system_lib_path: java_library_path(),
4849
};
4950

5051
let runtime = JavaServiceRuntime::new(config, internal_config);

exonum-java-binding/core/rust/src/runtime/cmd.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use std::path::PathBuf;
3131
// Parameters for `run` command
3232
const EJB_LOG_CONFIG_PATH: &str = "EJB_LOG_CONFIG_PATH";
3333
const EJB_PORT: &str = "EJB_PORT";
34+
const EJB_OVERRIDE_LIBRARY_PATH: &str = "EJB_OVERRIDE_LIBRARY_PATH";
3435
const JVM_DEBUG_SOCKET: &str = "JVM_DEBUG_SOCKET";
3536
const JVM_ARGS_PREPEND: &str = "JVM_ARGS_PREPEND";
3637
const JVM_ARGS_APPEND: &str = "JVM_ARGS_APPEND";
@@ -62,6 +63,15 @@ impl CommandExtension for Run {
6263
"ejb-log-config-path",
6364
false,
6465
),
66+
Argument::new_named(
67+
EJB_OVERRIDE_LIBRARY_PATH,
68+
false,
69+
"Overrides the standard path to native libraries, enabling running the non-packaged \
70+
exonum-java application. Mostly for internal usage.",
71+
None,
72+
"ejb-override-java-library-path",
73+
false,
74+
),
6575
Argument::new_named(
6676
JVM_DEBUG_SOCKET,
6777
false,
@@ -97,6 +107,7 @@ impl CommandExtension for Run {
97107
.arg(EJB_LOG_CONFIG_PATH)
98108
.unwrap_or_else(|_| get_path_to_default_log_config());
99109
let port = context.arg(EJB_PORT)?;
110+
let override_system_lib_path = context.arg(EJB_OVERRIDE_LIBRARY_PATH).ok();
100111
let args_prepend: Vec<String> = context.arg_multiple(JVM_ARGS_PREPEND).unwrap_or_default();
101112
let args_append: Vec<String> = context.arg_multiple(JVM_ARGS_APPEND).unwrap_or_default();
102113
let jvm_debug_socket = context.arg(JVM_DEBUG_SOCKET).ok();
@@ -110,6 +121,7 @@ impl CommandExtension for Run {
110121
let runtime_config = RuntimeConfig {
111122
log_config_path,
112123
port,
124+
override_system_lib_path,
113125
};
114126

115127
let config = Config {

exonum-java-binding/core/rust/src/runtime/config.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,18 @@ pub struct RuntimeConfig {
5555
/// A port of the HTTP server for Java services.
5656
/// Must be distinct from the ports used by Exonum.
5757
pub port: i32,
58+
/// Overridden path to native library if specified.
59+
pub override_system_lib_path: Option<String>,
5860
}
5961

6062
/// Internal EJB configuration.
6163
///
6264
/// Not visible by user, used internally while initializing runtime.
63-
#[doc(hidden)] // For testing purposes only.
6465
pub struct InternalConfig {
6566
/// EJB system classpath.
6667
pub system_class_path: String,
6768
/// EJB library path.
68-
pub system_lib_path: Option<String>,
69+
pub system_lib_path: String,
6970
}
7071

7172
/// Error returned while validating user-specified additional parameters for JVM.

exonum-java-binding/core/rust/src/runtime/java_service_runtime.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -202,20 +202,19 @@ impl JavaServiceRuntime {
202202

203203
/// Adds required EJB-related arguments to JVM configuration.
204204
fn add_required_arguments(
205-
mut args_builder: InitArgsBuilder,
205+
args_builder: InitArgsBuilder,
206206
runtime_config: &RuntimeConfig,
207207
internal_config: InternalConfig,
208208
) -> InitArgsBuilder {
209-
// We do not use system library path in tests, because an absolute path to the native
210-
// library will be provided at compile time using RPATH.
211-
if internal_config.system_lib_path.is_some() {
212-
args_builder = args_builder.option(&format!(
213-
"-Djava.library.path={}",
214-
internal_config.system_lib_path.unwrap()
215-
));
216-
}
209+
// Use overridden system library path if any.
210+
let system_lib_path = if runtime_config.override_system_lib_path.is_some() {
211+
runtime_config.override_system_lib_path.clone().unwrap()
212+
} else {
213+
internal_config.system_lib_path
214+
};
217215

218216
args_builder
217+
.option(&format!("-Djava.library.path={}", system_lib_path))
219218
.option(&format!(
220219
"-Djava.class.path={}",
221220
internal_config.system_class_path

exonum-java-binding/core/rust/src/runtime/service_factory_adapter.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ use exonum::{
1818
};
1919
use runtime::{
2020
cmd::Run,
21-
config::{Config, InternalConfig},
21+
config::Config,
2222
java_service_runtime::JavaServiceRuntime,
2323
paths::{absolute_library_path, system_classpath},
2424
};
2525
use std::sync::{Once, ONCE_INIT};
26+
use InternalConfig;
2627

2728
static mut JAVA_SERVICE_RUNTIME: Option<JavaServiceRuntime> = None;
2829
static JAVA_SERVICE_RUNTIME_INIT: Once = ONCE_INIT;
@@ -53,20 +54,25 @@ impl JavaServiceFactoryAdapter {
5354
fn get_or_create_java_service_runtime(config: Config) -> JavaServiceRuntime {
5455
// Initialize runtime if it wasn't created before.
5556
JAVA_SERVICE_RUNTIME_INIT.call_once(|| {
56-
let internal_config = InternalConfig {
57-
system_class_path: system_classpath(),
58-
system_lib_path: Some(absolute_library_path()),
59-
};
60-
61-
let runtime = JavaServiceRuntime::new(config, internal_config);
62-
unsafe {
63-
JAVA_SERVICE_RUNTIME = Some(runtime);
64-
}
57+
Self::create_runtime(config);
6558
});
6659

6760
unsafe { JAVA_SERVICE_RUNTIME.clone() }
6861
.expect("Trying to return runtime, but it's uninitialized")
6962
}
63+
64+
// Actually creates the runtime. Should be called only once.
65+
fn create_runtime(config: Config) {
66+
let internal_config = InternalConfig {
67+
system_class_path: system_classpath(),
68+
system_lib_path: absolute_library_path(),
69+
};
70+
71+
let runtime = JavaServiceRuntime::new(config, internal_config);
72+
unsafe {
73+
JAVA_SERVICE_RUNTIME = Some(runtime);
74+
}
75+
}
7076
}
7177

7278
impl ServiceFactory for JavaServiceFactoryAdapter {
@@ -95,7 +101,7 @@ impl ServiceFactory for JavaServiceFactoryAdapter {
95101
}
96102
}
97103

98-
// Returns the real command extension for the first call and `None` for any other call.
104+
// Returns `true` for the very first call, `false` otherwise.
99105
fn is_first_instance_created() -> bool {
100106
let mut is_first = false;
101107
FIRST_INSTANCE_CREATED.call_once(|| is_first = true);

0 commit comments

Comments
 (0)