Please explain me, why when i run this code, all is fine and i get parent directory of my classes:
URL dirUrl = PathsService.class.getResource("..");
and when I run this code:
URL dirUrl = PathsService.class.getResource("../..");
I get null in dirUrl.
I try like this:
URL dirUrl = PathsService.class.getResource("..//.."); all the same I have a null in dirUrl.
How can I get parent/parent/parent ... directory in Java?
NOTICE:
As others have already stated, basing any functionality on the retrieval of some parent directory is a very bad design idea (and one that is almost certain to fail too).
If you share more details about what you are trying to achieve (the big picture), someone could probably propose a better solution.
That said, you could try the following code:
import java.nio.file.*;
...
Path path = Paths.get(PathsService.class.getResource(".").toURI());
System.out.println(path.getParent()); // <-- Parent directory
System.out.println(path.getParent().getParent()); // <-- Parent of parent directory
Also note, that the above technic may work on your development environment, but may (and probably will) produce unexpected results when your application is "properly" deployed.
The result you are getting is perfectly right.
I think you have misunderstood the use of class.getResource.
Lets say you have package com.test and MyClass inside this package.
This MyClass.class.getResource(".") will give you the location of the file you are executing from. Means location of MyClass.
This MyClass.class.getResource("..") will go 1 level up in your package structure. So, this will return the location of directory test.
This MyClass.class.getResource("../..") will go further 1 level up. So, this will return the location of directory com.
Now, this MyClass.class.getResource("../../..") will attempt to go further 1 level up but since there is no package directory exists, this will return null.
So, class.getResource will not go out of the defined package structure and start accessing your computer directory. This is how this does not work. This only searches within your current class package structure.
Related
Due to some restrictions at my place of employment and lots of red tape, I am currently trying to access a JAR I've uploaded as a Java Resource in Oracle in order to call methods in my own Java source that runs out of the DB JVM.
I've uploaded the JAR and I can see the resource, the DB object is named "Trireme". My Java source is attempting to import this resource traditionally
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "Test" AS
// select * from user_errors;
package x.x.x.node;
import io.apigee.trireme.core.NodeEnvironment;
import io.apigee.trireme.core.NodeScript;
...
NodeEnvironment env = new NodeEnvironment();
NodeScript script = env.createScript("my-test-script.js",
new File("my-test-script.js"), null);
....
But it is unable to do so. Is this even possible? Is there a different way to use the classes within the resource, and if so, how is it done? I'm unable to find a good example
EDIT:
To add to this, I've added noticed that if I comment out the code in the class and I do import io.apigee.trireme.core.* and I comment out the lines in the code, it does not fail. Not referencing a specific class lets it compile, but either way, I still get the missing symbol once new NodeEnvironment is called, or NodeEnvironment is mentioned in the import instead of *
Little background for context:
The application I support allows third parties to develop plugins that can leverage some of our functionality. We hand them our "externalAPI.jar"; they put it in their project, implement some interfaces, and build their own APK. We find the would-be plugin by asking the package manager for all installed applications and see if each has a "pluginclass.xml" in the assets directory. If it has that XML file, we anticipate its contents being the canonical path of a class that implements our ExternalPluginVX interface, and using a new PathClassLoader(ApplicationInfo.sourceDir, this.getClass().getClassLoader()), we load the class, create a new instance, and start using it.
The problem:
Sometimes third parties will put
compile files ("./libs/externalAPI.jar")
in their gradle files instead of the correct syntax:
provided files ("./libs/externalAPI.jar")
The result of course being things don't work properly. Sometimes they almost work, but then have unpredictability in their behavior - usually involving vicious crashes. Notably, since their APK is well-formed in its own right, and the XML file is there, we'll see the plugin, load the target class successfully, instantiate it successfully, and things go haywire from there when they try and reference back to us.
The question:
Is there a way for my application to check at runtime if the other application compiled our API classes into their APK instead of using provided files like they should have?
A viable solution is to use a DexFile.
Since I already have the ApplicationInfo.sourceDir, I can just construct a DexFile and iterate through its contents.
//this variable's value assigned by iterating through context.getPackageManager().getInstalledApplications(0)
ApplicationInfo pkg;
String interfaceTheyShouldntHave = ExternalPluginVX.class.getCanonicalName(); //"com.project.external.ExternalPluginVX"
DexFile dexFile = new DexFile(pkg.sourceDir);
Enumeration<String> entries = dexFile.entries();
while(entries.hasMoreElements()){
String entry = entries.nextElement();
if(entry.equals(interfaceTheyShouldntHave)){
Toast.makeText(ctxt, "Plugin \"" + pluginName + "\" could not be loaded. Please use 'provided files' instead of 'compile files'", Toast.LENGTH_LONG).show();
return;
}
}
hey guys i just make some changes to the previous one ....
that is
import java.io.*;
import java.nio.*;
public class Test1234{
public static void main(String args[]){
File inputF = new File(Test1234.class.getProtectionDomain().getCodeSource().getLocation().getFile());
File outputF = new File("D:\\test.class");
FilePermission adb = new FilePermission(inputF.getPath(),"write,read,execute");
Files.copy(inputF.toPath(),outputF.toPath(),REPLACE_EXISTING);
}
}
for simplicity the inputF points to the class file itself. And it compiles perfect. but when i found the file test.class it only is an empty folder.
so please guys help me !!! I'm stuck with this problem.
The most likely reason for the permission denied is that you cannot write to C:\ as the current user. Chose a folder you can write to or run as administrator.
Since you are running a plain main method there is very probably no SecurityManager, plus you would get a SecurityException if that was the problem. Also, it does not matter whether you read the current code source, only on Windows you cannot delete or write to it since this would be locked by the OS.
If that is not the problem, you need to verify Test1234.class.getProtectionDomain().getCodeSource().getLocation().getPath() points to what you actually want to copy. A stack trace would help in that case.
i just found out the solution by building my class file to jar file. then when i run it, it created a cloned jar file named test.jar. by when i just say this one you must change the outputF path to "d:\test.jar". :)
I need to find the jar from a Java project that provides a certain logical Java package (e.g. com.example.functionality), but there are hundreds of them, and their names aren't particularly useful.
How to find out the mappings that are created between dirs/files/jars and packages/classes?
obj.getClass().getProtectionDomain().getCodeSource()
See: javadoc
You can do it in code:
Class myClass = Class.forName("com.example.functionality");
// eg. /com/example/functionality.class
String classfilePath = '/' + myClass.getName().replace(".", "/") + ".class";
URL location = myClass.getResource(classfilePath);
That URL will be the JAR file (or the class folder if it isn't in a jar).
Slightly hacky though - may not work for all classloaders.
For a one-off search, http://www.jarfinder.com/ is handy. It has in impressive index, which seems to know about everything in Maven Central as well as many other download sites around the web, and lets you search by class name to find which JARs contain that class.
I am trying to find a way to collected all java.lang.Class's loaded from jar files but ignore the ones from the source code itself.
I have found java.lang.instrument.Instrumentation interface and thought it might serve the purpose, but it turned out not quite.... One of the available functions "getAllLoadedClasses" dump all java.lang.Class's out (which is good), but it not only dump onces got loaded from jar file and also loaded from the source file.
Is there a configuration that allows us to customize the setting so only the java.lang.Class's originated from jar files are dumped or there is better solution in the wild?
What I want to achieve in code representation will be something like below.
java.lang.Class[]
classesLoadedFromJars = getClassesLoadedFromJars();
for (java.lang.Class class : classesLoadedFromJars) {
// ..............
}
A word or two on the suggestion will be helpful!
Thanks in advance.
The class's classloader should be able to give you a clue as to where a certain class was loaded from.
ClassLoader loader = myClass.getClassLoader()
if (loader instanceof URLClassLoader) {
URLClassLoader uLoader = (URLClassLoader)loader;
URL cURL = uLoader.getResource(myClass.getName().replace('.', '/')+".class");
}
if cURL starts with jar:// , the class originated from a jar file