node-java-bridge

A bridge between Node.js and Java

MIT License

Downloads
8.9K
Stars
102
Committers
4

Bot releases are visible (Hide)

node-java-bridge - Release v2.6.0 Latest Release

Published by github-actions[bot] 6 months ago

Major changes

Errors thrown by the java process are now returned to the node process

Added a new property to each error, called cause which will contain the throwable from the Java process (if present):

import type { JavaError } from 'java-bridge';

try {
    // Call a method that throws an error
    someInstance.someMethodSync();
} catch (e: unknown) {
    const throwable = (e as JavaError).cause;
    throwable?.printStackTraceSync();
}

Added a config option called asyncJavaExceptionObjects to control whether the Java throwable should be returned from async contexts. This is required as enabling this option will cause the JavaScript stack trace to be lost. This option is disabled by default.

import { importClass, JavaError } from 'java-bridge';

const SomeClass = importClass('path.to.SomeClass', {
    asyncJavaExceptionObjects: true,
});

try {
    await SomeClass.someMethod();
} catch (e: unknown) {
    const throwable = (e as JavaError).cause;
    throwable?.printStackTraceSync();
}

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.5.2...v2.6.0

node-java-bridge - Release v2.5.2

Published by github-actions[bot] 7 months ago

Major changes

Added an option to manually release objects

import { importClass, deleteObject } from 'java-bridge';

const JString = importClass('java.lang.String');
const string = new JString('Hello World');

// Release the string, allowing the java process to garbage collect it
deleteObject(string);

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.5.1...v2.5.2

node-java-bridge - Release v2.5.1

Published by github-actions[bot] 8 months ago

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.5.0...v2.5.1

node-java-bridge - Release v2.5.0

Published by github-actions[bot] 8 months ago

NOTE: This version is broken, please use v2.5.1 instead.

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.4.0...v2.5.0

node-java-bridge - Release v2.4.0

Published by github-actions[bot] about 1 year ago

Major changes

Improved object to string conversion

Previously, when a java object was converted to a string using an implicit conversion,
the toString method of the java object wasn't used. Instead, the js object representation
was returned as a string.

In order to improve this behaviour, the toString method now returns a string instead
of a Promise<string>, a toStringAsync method returning a Promise<string> was added
and the toStringSync method has been deprecated.

Now, the toString method of the java object is properly utilized in order to convert an object
to a string:

import { importClass } from 'java-bridge';

const ArrayList = importClass('java.util.ArrayList');
const list = new ArrayList();

list.addSync('Hello');
list.addSync('World');

// Convert the list to a string (implicit conversion)
const str = list + ''; // [Hello, World]

Improved the conversion of objects to a string inside console.log

This improved conversion also applies to objects passed into console.log,
when the customInspect config setting is set to true:

import { importClass, config } from 'java-bridge';

config.customInspect = true;
const ArrayList = importClass('java.util.ArrayList');
const list = new ArrayList();

list.addSync('Hello');
list.addSync('World');

console.log(list); // [Hello, World]

Added more config options

A few rules around the configuration of the module have changed:

  • The configuration is now bound to a java class proxy. This means,
    the config cannot be for a specific class, once this class has been imported
    explicitly or implicitly (as a dependency of some sorts) using importClass
    or importClassAsync. This means, that the config should be set before importing
    a class. If you still want to change the config afterwards, you need to call the
    clearClassProxies method before re-importing a class with an updated config, in order
    to apply the config to the newly imported class.
  • The config may now be reset to its default values using config.reset().
  • The whole config can now be updated at once using the config.config setter.

Added options to set custom sync and async suffixes

Sync and async suffixes may now be set to custom values using the
syncSuffix and asyncSuffix config values.
Please note, that these values cannot be equal. If equal values
are set for both values, an error will be thrown inside the specific
setter. These options do not affect standard methods of java classes
like toString, toStringSync, toStringAsync and newInstanceAsync.

import { importClass, config, clearClassProxies } from 'java-bridge';

// Set the async suffix in order to prevent errors
config.asyncSuffix = 'Async';
// Set the sync suffix to an empty string
config.syncSuffix = '';
// This would do the same
config.syncSuffix = null;

// Clear the class proxy cache
clearClassProxies();

// Import the class
const ArrayList = importClass('java.util.ArrayList');

// Create a new instance
const list = new ArrayList();

// Call the method
list.add('Hello World!');

// Async methods now have the 'Async' suffix
await list.addAsync('Hello World!');

Added an option to importClass and importClassAsync in order to override the config

The config for a specific class or class import can be temporarily
overriden by passing a config object to importClass or importClassAsync.
This config passed does not apply to any classes transiently imported by this call,
nor does it affect any other imports (even ones of the same class).

import { importClass } from 'java-bridge';

const JavaString = importClass('java.lang.String', {
  syncSuffix: 'SyncSuffix',
});

const str = new JavaString('test');

str.containsSyncSuffix('e'); // true

Added support for logging

A special version of the module may be built which includes support for
logging. This requires the module to be built using npm run build:all.
Refer to the logging section of the readme
for further information on logging.

The settings for logging are located inside the logging namespace:

import { logging } from 'java-bridge';

logging.initLogger('log4rs.json');
logging.setLogCallbacks(
  (out) => console.log(out),
  (err) => console.error(err)
);

The full documentation for the module is available through the jsdoc of
the module once it has been built with logging support.

If the current build does not support logging, all methods inside
the logging namespace will be dummies and print an error message
to stdout once called (the message will only be printed once per
program execution).

Enhanced stack traces of async method calls

The stack traces returned by errors thrown inside asnyc contexts
now return the full stack trace including the stack trace on
the javascript side. A call like

import { importClass } from 'java-bridge';

const JavaString = importClass('java.lang.String');
await JavaString.newInstanceAsync(null);

will now throw:

Error: java.lang.NullPointerException: Cannot invoke "java.lang.StringBuffer.toString()" because "buffer" is null
    at java.base/java.lang.String.<init>(String.java:1446)
    at crates\java-rs\src\java\java_env_wrapper.rs:1371
    at crates\java-rs\src\java\java_env_wrapper.rs:304
    at C:\workspace\test.js:56:13
    at Object.<anonymous> (C:\workspace\test.js:57:3)
    at Module._compile (node:internal/modules/cjs/loader:1226:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1280:10)
    at Module.load (node:internal/modules/cjs/loader:1089:32)
    at Module._load (node:internal/modules/cjs/loader:930:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:23:47 {
  code: 'GenericFailure'
}

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.3.0...v2.4.0

node-java-bridge - Release v2.3.0

Published by github-actions[bot] over 1 year ago

Major changes

Moved the typescript definition generator to its own package

In order to reduce the number of dependencies, the typescript definition generator was moved to its own npm package and repository.

In order to install the package, simply run

npm install -g java-ts-definition-generator

The repository can be found here.

What's Changed

New Contributors

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.2.3...v2.3.0

node-java-bridge - Release v2.2.3

Published by github-actions[bot] over 1 year ago

Core changes

Allow proxies to be used in a synchronous context (experimental)

Added a new option called java.config.runEventLoopWhenInterfaceProxyIsActive to enable proxies to be used in a synchronous context.
This is an experimental feature and, in some cases, may cause your program to crash.

java.config.runEventLoopWhenInterfaceProxyIsActive = true;
const proxy = java.newProxy('java.util.function.Function', {
  apply: (arg: string): string => arg.toUpperCase();
});

const JavaString = java.importClass('java.lang.String');
const str = new JString('hello');

const res = str.transformSync(proxy);
// prints 'HELLO'
console.log(res);

Allow proxies to be used after they have been garbage collected

Added a new option to newProxy which allows proxies to stay alive longer than the javascript proxy object they were previously bound to:

const proxy = java.newProxy('java.lang.Runnable', {
   run: (): void => {
     console.log('Hello World!');
   }
}, {
   keepAsDaemon: true
});

const TimeUnit = java.importClass('java.util.concurrent.TimeUnit');
const ScheduledThreadPoolExecutor = java.importClass(
    'java.util.concurrent.ScheduledThreadPoolExecutor'
);
const executor = new ScheduledThreadPoolExecutor(1);

// 'proxy' will eventually be garbage collected,
// but it will be kept alive due to this option.
executor.scheduleAtFixedRateSync(proxy, 0, 1, TimeUnit.SECONDS);

// Calling proxy.reset won't do anything, in order to destroy a daemon
// proxy, the 'force' argument must be set to true
proxy.reset(true);

// Delete all daemon proxies. This will cause the executor to stop
// due to an exception thrown in the run method since the proxy
// is now invalid
java.clearDaemonProxies();

Auto-generated interface proxy definitions

The typescript definition generator now generates definitions for newProxy on interfaces:

import { createRunnableProxy } from './java/lang/Runnable';

const proxy = createRunnableProxy({
  run() {
    console.log('Hello World');
  }
});

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.2.2...v2.2.3

node-java-bridge - Release v2.2.2

Published by github-actions[bot] over 1 year ago

What's Changed

Note: Version 2.2.1 has been skipped due to deployment issues

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.2.0...v2.2.2

node-java-bridge - Release v2.2.2-rc.1

Published by github-actions[bot] almost 2 years ago

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.2.0...v2.2.2-rc.1

node-java-bridge - Release v2.2.0

Published by github-actions[bot] almost 2 years ago

Core changes

Generate Typescript definitions for Java classes in bulk

A new class, TypescriptBulkDefinitionGenerator has been added in order to generate a lot of Typescript definitions for Java classes more easily:

import { TypescriptBulkDefinitionGenerator } from 'java-bridge';

const generator = new TypescriptBulkDefinitionGenerator();

// Generate definitions for the named classes
await generator.generate([
     'java.io.FileOutputStream',
     'java.io.FileInputStream',
     'java.io.File',
     'java.lang.System',
]);

// Retrieve the generated code
const definitions = generator.moduleDeclarations;

// Save the definitions to a directory
await generator.save('javaDefinitions');

Change the classpath at startup more easily

In order to make changing the classpath before starting the JVM more easy, two new options have been added to ensureJvm:

  • classpath: string[] - Single files or glob patterns to add to the classpath
  • ignoreUnreadableClassPathEntries: boolean - Whether to ignore unreadable files in the classpath

With these new options, the classpath can be altered more easily, making sure some libraries like Spring Boot, which use a custom class loader can access all required dependencies at runtime, which is not guaranteed when using appendClasspath.

import { ensureJvm } from 'java-bridge';

ensureJvm({
	classpath: [
		'/path/to/your/lib.jar',
		// Glob patterns for adding directories are supported
		'/path/to/a/directory/*',
		// This also allows for adding only files of a specific type
		'/path/to/files/*.jar',
	],
	// Don't throw an error if a file is unreadable
	ignoreUnreadableClassPathEntries: true,
});

Additionally, ensureJvm now returns a boolean representing if the JVM has already been started by a previous call to java-bridge.
It returns true if the JVM has not already been started and this call to ensureJvm was responsible for creating the JVM, if the call returns false, the JVM has already been started by another call to java-bridge and this call to ensureJvm was basically a no-op.

import { ensureJvm } from 'java-bridge';

const started = ensureJvm();
if (!started) {
	throw new Error('Failed to start the JVM as it is already running');
}

Glob patterns for appendClasspath

As with ensureJvm, appendClasspath now supports glob patterns to add directories more easily:

import { appendClasspath } from 'java-bridge';

// Import a directory recursively
appendClasspath('/path/to/files/**/*');

// Import multiple files at once
appendClasspath([
	'/path/to/your/file.jar',
	// Again, this allows for only adding files of a specific type
	'/path/to/some/files/*.jar',
]);

This of course also works with classpath.append:

import { classpath } from 'java-bridge';

// Import all jars inside directories recursively
classpath.append('/path/to/many/files/**/*.jar')

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.1.7...v2.2.0

node-java-bridge - Release v2.1.7

Published by github-actions[bot] almost 2 years ago

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.1.6...v2.1.7

node-java-bridge - Release v2.1.6

Published by github-actions[bot] almost 2 years ago

What's Changed

  • fix: method arguments not being parsed properly by @MarkusJx in https://github.com/MarkusJx/node-java-bridge/pull/30
    • fixed constructor arguments getting truncated
    • fixed fields containing null values throwing errors
    • fixed an issue where passing class instances representing primitives caused the method/constructor to not be found
    • fixed public properties not being added to class instances
    • made long return types always return bigint

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.1.5...v2.1.6

node-java-bridge - Release v2.1.5

Published by github-actions[bot] almost 2 years ago

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.1.4...v2.1.5

node-java-bridge - Release v2.1.5-beta.1

Published by github-actions[bot] almost 2 years ago

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.1.4...v2.1.5-beta.1

node-java-bridge - Release v2.1.4

Published by github-actions[bot] about 2 years ago

What's Changed

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.1.3...v2.1.4

node-java-bridge - Release v2.1.3

Published by github-actions[bot] about 2 years ago

What's changed

  • Fixed typescript compile errors

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.1.2...v2.1.3

node-java-bridge - Release v2.1.2

Published by github-actions[bot] about 2 years ago

What's Changed

  • Fixed a runtime error when calling the typescript definition generator

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.1.1...v2.1.2

node-java-bridge - Release v2.1.1

Published by github-actions[bot] about 2 years ago

What's Changed

  • Fixed an issue which caused the program execution to halt when multiple interface proxies are in use

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.1.0...v2.1.1

node-java-bridge - Release v2.1.0

Published by github-actions[bot] about 2 years ago

What's Changed

  • Renamed the module to java-bridge
  • Bumped the required node.js version to 15
  • Set the target version of the java library to 1.8
  • Added an instanceOf method to class instances:
import { importClass } from 'java-bridge';

const JavaString = importClass('java.lang.String');
const str = new JavaString('Hello World');

// Pass the class to check against as the argument
str.instanceOf(JavaString); // true

// You can also pass the name of the class to check against
str.instanceOf('java.lang.String'); // true
str.instanceOf('java.lang.Object'); // true
str.instanceOf('java.util.List'); // false

Full Changelog: https://github.com/MarkusJx/node-java-bridge/compare/v2.0.1...v2.1.0

node-java-bridge - Release v2.1.0-beta.2

Published by github-actions[bot] about 2 years ago

Release for testing purposes