Docker Class.forName doesn't find class - java

I'm running a server in a docker image openjdk:8-jdk-slim.
Inside this server, using spring boot, I receive from the frontend a protobuf file, compile it and add the generated class to the classpath in runtime. I then proceed to use java reflection to get the added class, with the method Class.forName().
Outside of docker, when running in my pc, it works like a charm. However, when I run in docker when I try to access using the method Class.forName(), with the same class name I use when not in docker, it doesn't find the class.
Is there something that I am missing because it is docker?
Edit for more information:
I'm running a maven build inside docker. What I have in this specific operation is an endpoint that receives a byte array, which corresponds to a protobuf file. I "construct" a file with this byte array, save it in a specific folder. I proceed to compile it with the protoc compiler, which generates a .java file, which I save in a specific folder. This folder corresponds to a package, which we will call "xxx.yyy.zzz".
When I try to add the class to the classpath, using this code -
File newClass = new File(relativePath);
URL url = newClass.toURI().toURL();
URLClassLoader classLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();
Method newMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
newMethod.setAccessible(true);
newMethod.invoke(classLoader, url);
I provide the relativePath to the .class file but it isn't added to the classpath. I know that the .class file is generated in the correct way and is saved in the specific folder.

Related

Unable to Access External Jar in Spark

I am trying to run Spark locally in my Intellij and passing in an external jar with sparkConf:
sparkConf.set("spark.jars", "C:\\path\\to\\my\\jar.jar");
I see in the console when running that the jar has been added:
INFO org.apache.spark.SparkContext:57 - Added JAR C:\\path\\to\\my\\jar.jar at spark://some spark path
I also see the jar in Spark UI underneath Classpath Entries:
some-spark-path Added By User
However I am running into two issues.
When I tried to call upon a resource file in the external jar via code below, I get a null for the Inputstream, path would be like "/file/i/need.json":
try(InputStream is= SomeClass.class.getResourceAsStream(path))
When I am also passing a className (this class exists in the external jar) as string to a method which then creates an instance, I get ClassNotFoundException. ClassName would be like "class.i.need":
Class<?> classes = Class.forName(className);
Any advice would be helpful. Thanks!
Edit: Running on Spark 3.0.0.
I have also tried with "spark.driver.extraClassPath" to no avail.

Store a file inside a jar library

How do you store a file inside a jar library?
Setup :
Create a simple maven project with a class that loads something from the resources folder using the getResoruceAsStream() method and a test that runs it. The test will fail with the problem being it couldn't find that file, the same issue will appear later when we try to compile it as a lib and run that class.
The problem : Using the only method I know (and the only that you can find on the web) getResourceAsStream() will give you a null reference exception, because the file is missing. So how do I add the file to the jar and load it later?
Keep the file in the src/main/resources directory and use the following method in the class where you need to load that file -
private InputStream readFileFromResourcePath(String filename) {
return getClass().getClassLoader().getResourceAsStream(filename);
}
Do not forget to close the stream after consuming it.

Provide DLL path to System.loadLibrary on export

I want to export my Java application which uses JNI interface, and loads a DLL via System.loadLibrary("dllName").
The DLL file is present inside Java Project folder as well as in C drive, one of places where JVM will search for DLL at runtime.
Problem: When I export this project out as a Jar and give it to client, client should be able to run the tool without hassles of entering a Dll file. I can't think of accomplishing this via alternative way; to provide absolute path by using System.load("path:\\") because I don't know where the user would download the Jar file to.
The following snippet will load the DLL regardless of the working directory if it's loacted in the same directory as the JAR file:
CodeSource codeSource = MainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
File parentDir = jarFile.getParentFile();
File dllFile = new File(parentDir, "my.dll");
System.load(dllFile.getPath());
You need to put the DLL in the same path that the application is running, in a system path or add its path the PATH variable before starting the app.
Have a look at Runtime.load.
Loads the specified filename as a dynamic library. The filename
argument must be a complete path name. From java_g it will
automagically insert "_g" before the ".so" (for example
Runtime.getRuntime().load("/home/avh/lib/libX11.so");).
First, if there is a security manager, its checkLink method is called
with the filename as its argument. This may result in a security
exception.
This is similar to the method loadLibrary(String), but it accepts a
general file name as an argument rather than just a library name,
allowing any file of native code to be loaded.
The method System.load(String) is the conventional and convenient
means of invoking this method.

Loading a resource in a JAR file

I have a Java project in Netbeans. It runs fine with Maven. So I assembled it. It contains the following code to load a file that is in the JAR:
ClassLoader loader = MyClass.class.getClassLoader();
SERVICE_URL = loader.getResource("my.wsdl");
This returns a URL like:
jar:file:/path/to/my/file/MyClass-1.0-SNAPSHOT-jar-with-dependencies.jar!/my.wsdl
but the library that needs this parameter doesn't appear to be able to use it.
Is there any way this file can be in the JAR and be referred to from the code like this?
You may have to use ClassLoader.getResourceAsStream(), copy it to a temporary file, and then create a URL with File.toURI().toURL()

How to get current path when program is loaded dynamically

I'm not able to give this question an apt title so apology for that.
I am making a modularised application. I load various jar files at runtime and invoke particular method of a particular class (of the jar file) at run time.
The jar file has some supported file. Now my jar file uses another application , lets say abc which is located in the same directory where i have kept the jar file. When i run the jar file then
new File(".").getAbsolutePath()
gives the correct path (this is where abc is located) and program runs fine. But when i load this jar file dynamically and invoke method using reflection above code gives the path of the parent program and abc is not found at that path.
Now my question is how do i find the path in which my jar file exists when i'm running my jar file's code using reflection.
Please let me know if you need more explanation.
Try something like this:
public static void main(String[] args) {
System.out.println(StringUtils.class.getResource("StringUtils.class"));
}
(Note: StringUtils is present on my classpath as a Maven dependency at the time) This gives me:
jar:file:/home/******/.m2/repository/org/apache/commons/commons-lang3/3.4/commons-lang3-3.4.jar!/org/apache/commons/lang3/StringUtils.class
Since the class is in a JAR file, it also gives me the location of the class file within the JAR.

Categories

Resources