diff --git a/docs/articles/usage.html b/docs/articles/usage.html index f77a43d1ba..99e3d7c2e8 100644 --- a/docs/articles/usage.html +++ b/docs/articles/usage.html @@ -71,6 +71,45 @@
To use JNet classes the developer can write code in .NET using the same classes available in the official Java packages. If classes or methods are not available yet it is possible to use the approach synthetized in What to do if an API was not yet implemented
+JNet accepts many command-line switches to customize its behavior. The full list is available at Command line switch page.
+One of the most important command-line switch is JVMPath and it is available in JCOBridge switches: it can be used to set-up the location of the JVM library (jvm.dll/libjvm.so) if JCOBridge is not able to identify a suitable JRE installation. +If a developer is using JNet within its own product it is possible to override the JVMPath property with a snippet like the following one:
+ class MyJNetCore : JNetCore
+ {
+ public override string JVMPath
+ {
+ get
+ {
+ string pathToJVM = "Set here the path to JVM library or use your own search method";
+ return pathToJVM;
+ }
+ }
+ }
+
+IMPORTANT NOTE: pathToJVM
shall be escaped
string pathToJVM = "C:\\Program Files\\Eclipse Adoptium\\jdk-11.0.18.10-hotspot\\bin\\server\\jvm.dll";
string pathToJVM = @"C:\Program Files\Eclipse Adoptium\jdk-11.0.18.10-hotspot\bin\server\jvm.dll";
JCOBridge try to identify a suitable JRE/JDK installation within the system using some standard mechanism of JRE/JDK: JAVA_HOME
environment variable or Windows registry if available.
+However it is possible, on Windows operating systems, that the library raises an InvalidOperationException: Missing Java Key in registry: Couldn't find Java installed on the machine.
+This means that neither JAVA_HOME
nor Windows registry contains information about a default installed JRE/JDK: some vendors may not setup them.
+If the developer/user encounter this condition can do the following steps:
set | findstr JAVA_HOME
and verify the result;JAVA_HOME
environment variable is not set at system level, but at a different level like user level which is not visible from the JNet process that raised the exception;JAVA_HOME
at system level e.g. JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-11.0.18.10-hotspot\
;JCOBRIDGE_JVMPath
at system level e.g. JCOBRIDGE_JVMPath=C:\Program Files\Eclipse Adoptium\jdk-11.0.18.10-hotspot\
.IMPORTANT NOTES:
+JCOBRIDGE_JVMPath
or JAVA_HOME
environment variables or Windows registry (on Windows OSes) shall be availableJCOBRIDGE_JVMPath
environment variable takes precedence over JAVA_HOME
and Windows registry: you can set JCOBRIDGE_JVMPath
to C:\Program Files\Eclipse Adoptium\jdk-11.0.18.10-hotspot\bin\server\jvm.dll
and avoid to override JVMPath
in your codeJVMPath
takes precedence over JCOBRIDGE_JVMPath
/JAVA_HOME
environment variables or Windows registryBelow a basic example which demonstrates how to create a program based on JNet and some other features available like generics and exception handling. Within the program the comments try to explain how the code works.
@@ -102,7 +141,8 @@JNet accepts many command-line switches to customize its behavior. The full list is available at Command line switch page.
-One of the most important command-line switch is JVMPath and it is available in JCOBridge switches: it can be used to set-up the location of the JVM library (jvm.dll/libjvm.so) if JCOBridge is not able to identify a suitable JRE installation. -If a developer is using JNet within its own product it is possible to override the JVMPath property with a snippet like the following one:
- class MyJNetCore : JNetCore
+Avoid Java.Lang.NullPointerException
writing a good code
+Sometime during execution a Java.Lang.NullPointerException
can be raised and seems there isn't neither a real problem in the .NET code you wrote nor a specific pattern or time when it is raised.
+The problem is behind the scene and it is correlated on how Garbage Collector and code optimizer works.
+In the code of the previous chapter the Collections.Singleton("test")
creates an object which is used from set.Add(appArgs[0])
and in this case the Garbage Collector does not retires the object.
+Considering the following code snippet:
+using Java.Util;
+using MASES.JNet.Extensions;
+using System.Diagnostics;
+using Java.Lang;
+
+namespace MASES.JNetExample
+{
+ class MyJNetCore : JNetCore<MyJNetCore> { }
+
+ class Program
{
- public override string JVMPath
+ static void Main(string[] args)
{
- get
+ MyJNetCore.CreateGlobalInstance();
+ try
{
- string pathToJVM = "Set here the path to JVM library or use your own search method";
- return pathToJVM;
+ Java.Util.Set<string> set = Collections.Singleton("test");
+ ArrayList<string> arrayList = new();
+ arrayList.AddAll(0, set); // this point can raise Java.Lang.NullPointerException
}
+ catch (System.Exception ex) { System.Console.WriteLine(ex.Message); }
}
}
+}
-IMPORTANT NOTE: pathToJVM
shall be escaped
-
-string pathToJVM = "C:\\Program Files\\Eclipse Adoptium\\jdk-11.0.18.10-hotspot\\bin\\server\\jvm.dll";
-string pathToJVM = @"C:\Program Files\Eclipse Adoptium\jdk-11.0.18.10-hotspot\bin\server\jvm.dll";
-
-Special initialization conditions
-JCOBridge try to identify a suitable JRE/JDK installation within the system using some standard mechanism of JRE/JDK: JAVA_HOME
environment variable or Windows registry if available.
-However it is possible, on Windows operating systems, that the library raises an InvalidOperationException: Missing Java Key in registry: Couldn't find Java installed on the machine.
-This means that neither JAVA_HOME
nor Windows registry contains information about a default installed JRE/JDK: some vendors may not setup them.
-If the developer/user encounter this condition can do the following steps:
-
-- On a command prompt execute
set | findstr JAVA_HOME
and verify the result;
-- If something was reported maybe the
JAVA_HOME
environment variable is not set at system level, but at a different level like user level which is not visible from the JNet process that raised the exception;
-- Try to set
JAVA_HOME
at system level e.g. JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-11.0.18.10-hotspot\
;
-- Try to set
JCOBRIDGE_JVMPath
at system level e.g. JCOBRIDGE_JVMPath=C:\Program Files\Eclipse Adoptium\jdk-11.0.18.10-hotspot\
.
-
-IMPORTANT NOTES:
+the Collections.Singleton("test")
ends its life, from .NET point of view, when arrayList.AddAll(0, set)
is invoked:
-- One of
JCOBRIDGE_JVMPath
or JAVA_HOME
environment variables or Windows registry (on Windows OSes) shall be available
-JCOBRIDGE_JVMPath
environment variable takes precedence over JAVA_HOME
and Windows registry: you can set JCOBRIDGE_JVMPath
to C:\Program Files\Eclipse Adoptium\jdk-11.0.18.10-hotspot\bin\server\jvm.dll
and avoid to override JVMPath
in your code
-- After first initialization steps,
JVMPath
takes precedence over JCOBRIDGE_JVMPath
/JAVA_HOME
environment variables or Windows registry
+Java.Util.Set<string>
is a .NET container for JVM java.util.Set<String>
+arrayList.AddAll(0, set)
receives the Java.Util.Set<string>
instance and sends to JVM the reference to java.util.Set<String>
of JVM
+- from .NET point of view
Java.Util.Set<string>
has ended its life and can be retired because does not have any other root referencing it
+- .NET Garbage Collector activates arbitrarily when some conditions meet: https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/
+Most of the time the code above works without problem, but sometimes the JVM can raise a Java.Lang.NullPointerException
because Java.Util.Set<string>
was retired from .NET GC.
+To solve the issue, and force the GC to not retire the instance, there are some possible code snippet a developer can follows:
+using
or try-finally
with Dispose
patterns
+All classes implements IDisposable
interface, the code snippet becomes:
+using Java.Util;
+using MASES.JNet.Extensions;
+using System.Diagnostics;
+using Java.Lang;
+
+namespace MASES.JNetExample
+{
+ class MyJNetCore : JNetCore<MyJNetCore> { }
+
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ MyJNetCore.CreateGlobalInstance();
+ try
+ {
+ using (Java.Util.Set<string> set = Collections.Singleton("test"))
+ {
+ ArrayList<string> arrayList = new();
+ arrayList.AddAll(0, set);
+ }
+ }
+ catch (System.Exception ex) { System.Console.WriteLine(ex.Message); }
+ }
+ }
+}
+
+or
+using Java.Util;
+using MASES.JNet.Extensions;
+using System.Diagnostics;
+using Java.Lang;
+
+namespace MASES.JNetExample
+{
+ class MyJNetCore : JNetCore<MyJNetCore> { }
+
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ MyJNetCore.CreateGlobalInstance();
+ try
+ {
+ Java.Util.Set<string> set = null;
+ try
+ {
+ set = Collections.Singleton("test");
+ ArrayList<string> arrayList = new();
+ arrayList.AddAll(0, set);
+ }
+ finally { set?.Dispose(); }
+ }
+ catch (System.Exception ex) { System.Console.WriteLine(ex.Message); }
+ }
+ }
+}
+
+SuppressFinalize
/ReRegisterForFinalize
pattern
+Over every .NET object can be invoke the SuppressFinalize
, the code snippet becomes:
+using Java.Util;
+using MASES.JNet.Extensions;
+using System.Diagnostics;
+using Java.Lang;
+
+namespace MASES.JNetExample
+{
+ class MyJNetCore : JNetCore<MyJNetCore> { }
+
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ MyJNetCore.CreateGlobalInstance();
+ try
+ {
+ Java.Util.Set<string> set = Collections.Singleton("test");
+ try
+ {
+ System.GC.SuppressFinalize(set);
+ ArrayList<string> arrayList = new();
+ arrayList.AddAll(0, set);
+ }
+ finally { System.GC.ReRegisterForFinalize(set); }
+ }
+ catch (System.Exception ex) { System.Console.WriteLine(ex.Message); }
+ }
+ }
+}
+
diff --git a/docs/manifest.json b/docs/manifest.json
index af78cc4f78..f3d8431adf 100644
--- a/docs/manifest.json
+++ b/docs/manifest.json
@@ -63396,7 +63396,7 @@
"output": {
".html": {
"relative_path": "articles/usage.html",
- "hash": "dyMnYAytqlHpKY28VBfBluH0Ma1alHb1ZXtirNzZAns="
+ "hash": "cTawMw2ZiTo/593NjfMpbvpf4CJrtXzzlESakvOl7Bo="
}
},
"is_incremental": false,