有一个具有标准 Maven 文件夹结构的简单 Java 项目。
src
main
java
mypackage
Main.java
resource
abc
cde.txt
Run Code Online (Sandbox Code Playgroud)
Main.java(省略样板)
var path = "abc/cde.txt";
InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
if (input == null) {
throw new IllegalStateException("Resource not found");
} else {
// read from input
}
Run Code Online (Sandbox Code Playgroud)
该代码工作正常并从绝对路径
"%project_root%/target/classes/abc/cde.txt"(编译后的代码)读取文件。
添加文件后src/main/java/module-info.java情况发生变化:程序找不到文件并抛出in branch (input == null)。
如何以旧方式从“资源”文件夹中读取文件并同时拥有:资源文件夹中的java模块和资源?我想避免"src/main/resources"到处添加前缀。
我有一个主要方法,用于创建自定义类加载器并用它实例化一个名为 Test 的类。
public class App {
public static void main(String[] args) throws Exception {
try {
Class.forName("com.mycompany.app2.Test2"); // We ensure that Test2 is not part of current classpath
System.err.println("Should have thrown ClassNotFound");
System.exit(1);
} catch (ClassNotFoundException e) {
// ignore
}
String jar = "C:\\experiments\\classloader-test2\\target\\classloader-test2-1.0-SNAPSHOT.jar"; // Contains Test2
URL[] classPaths = new URL[] { new File(jar).toURI().toURL() };
ClassLoader classLoader = new URLClassLoader(classPaths, App.class.getClassLoader());
Thread.currentThread().setContextClassLoader(classLoader);
Class.forName("com.mycompany.app2.Test2", true, classLoader); // Check that custom class loader can find the wanted class
Test …Run Code Online (Sandbox Code Playgroud) java classloader urlclassloader classnotfoundexception java-17
我有两个程序:一个CLI程序和一个GUI.GUI是CLI的前端,也是另一个程序的GUI.
我正在导入CLI的类并在GUI中扩展它们以向类添加GUI元素,一切都很棒.
但现在我想拆分我目前嵌入GUI的CLI(作为一个包含的JAR).JAR位于一个固定的位置(/opt/program/prog.jar),该应用程序只能在Linux上使用,因此我意识到这打破了传统的Java思想.
我已经在Manifest文件中编辑了ClassPath以反映这一变化,并且它工作正常.但是,当我删除该文件时,GUI无法加载,因为无法加载该类.
有没有办法尝试加载一个类,如果它不起作用,那么做一些其他的?本质上,我试图捕获ClassNotFound异常,但还没有运气.
是否有一种简单的方法可以将我自己执行的JAR中的资源作为InputStream加载而无需访问ClassLoader?问题是我的java.policy限制访问ClassLoader(这不能更改).我想加载一些我可以放在我的JAR中的xml配置,但不能在JAR之外.
谢谢你的回答.实际上我的问题不在于我自己的ClassLoader.我正在使用XStream,它希望创建一些类加载器和应用程序崩溃:
java.security.AccessControlException:java.security.AccessController.checkPermission(AccessControlContext.java:323)的java.security.AccessController.checkPermission(AccessController.java:546)访问被拒绝(java.lang.RuntimePermission createClassLoader)java.lang .SecurityManager.checkPermission(SecurityManager.java:532)位于java.lang.ClassLlass的java.lang.SecurityManager.checkCreateClassLoader(SecurityManager.java:594).(ClassLoader.java:226)com.thoughtworks.xstream.core.util .CompositeClassLoader.(CompositeClassLoader.java:50)
我已经使用ASM对我的班级进行了检测并像这样处理了它
public class MyClassLoader extends ClassLoader {
...
byte[] classBytes = ... //the class is of type com.mypackage.Test
Class clazz = defineClass("com.mypackage.Test", classBytes, 0, classBytes.length);
resolveClass(clazz);
com.mypackage.Test test =(com.mypackage.Test) clazz.newInstance();
Run Code Online (Sandbox Code Playgroud)
但是我在最后一行得到ClassCastException:
java.lang.ClassCastException: com.mypackage.Test cannot be cast to com.mypackage.Test
Run Code Online (Sandbox Code Playgroud)
解决方法是使用反射:
Object test = clazz.newInstance();
test.getClass().getMethods()[0].invoke(test, null); //invoke some method - successfully
Run Code Online (Sandbox Code Playgroud)
我使用错误的类加载器还是什么?
我正在关注以下链接中的示例:
http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth.html?page=1 这是我得到的输出:
This program will use SimpleClassLoader.
>>>>>> Load class : TestClass
>>>>>> Not a system class.
>>>>>> Fetching the implementation of TestClass
file was read successfully
Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value 1768779887 in class file
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at aha.SimpleClassLoader.loadClass(SimpleClassLoader.java:80)
at aha.SimpleClassLoader.loadClass(SimpleClassLoader.java:42)
at aha.Example.main(Example.java:11)
这是我读取文件的方法的示例:
private byte getClassImplFromDataBase(String className)[] {
System.out.println(" >>>>>> Fetching the implementation of "+className);
byte result[];
try {
FileInputStream fi = new FileInputStream("C:/delete/"+className+".impl");
result = new …Run Code Online (Sandbox Code Playgroud) 当我在Java中进行大量类型检查时,如下所示:
if (clazz.equals(Byte.class) <dosomething>
if (clazz.equals(Integer.class) <dosomething>
...
Run Code Online (Sandbox Code Playgroud)
JVM是否加载了所有这些类(Byte,Integer?)如果确实如此,是否还有其他方法可以在不加载一堆我甚至不需要的类的情况下进行类类型检查?
我的Java应用程序有一个插件系统.我使用URL类加载器调用外部类.当我的应用程序作为类文件运行时,以及当我的应用程序处于JAR形式时,该部分运行良好.我遇到的问题是,插件文件可以运行他们自己的独立代码,但是他们创建了一个JPanel.当我尝试将JPanel添加到主应用程序类中的JPanel时,我得到一个引用主类的空指针异常.(com.cpcookieman.app.Main)但是如果我运行应用程序的类文件,只有在打包时才会发生这种情况.我怎么解决这个问题?
为什么我的代码打包到jar文件中会阻止外部类访问jar中的类?
编辑:根据要求,堆栈跟踪.
java.lang.NullPointerException
at TestPlugin2.Main.<init>(Main.java:23)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at com.cpcookieman.ph.PluginLoader$2.run(PluginLoader.java:74)
at java.lang.Thread.run(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
编辑2:类加载代码
String pluginsPath;
if (Main.os.equals("Windows"))
{
pluginsPath = "C:\\plugins\\";
}
else
{
pluginsPath = "~/plugins/";
}
File file = new File(pluginsPath);
if (!file.exists())
{
System.out.println("DEBUG: Plugin path could not be found!");
}
try
{
URL url = file.toURI().toURL();
final URL[] urls = new URL[]{url};
new Thread(new Runnable()
{
@Override
public void …Run Code Online (Sandbox Code Playgroud) 我知道JVM有一个单独的类加载器,它是加载类并执行它们的默认运行时方法.我只是想知道类加载如何适用于cpp.并且cpp中的类加载与操作系统中的动态加载有些相关.如果类没有动态加载,我想没有真正需要堆分配.但是cpp显然有free()内存选项.我有点困惑.它是如何工作的?
编辑:我理解为什么堆是对象初始化所必需的.但是我自己并不清楚静态或动态加载类本身的原因,特别是cpp的做法.
您好,感谢您抽出宝贵时间来研究这个问题。
我无法访问与src文件夹平行的文件夹中的文本文件(有关结构,请参见下文)。
我发现最接近的解释是:https : //www.cis.upenn.edu/~matuszek/cit597-2006/Pages/finding-files.html ,我遇到了许多类似的问题,但我都没有不幸的是可以推断出答案。
我知道我可以使用绝对路径,但是我想确保该软件可以在其他人的计算机上运行,所以这是不行的。因此,我试图使其与相对路径一起使用。
另外,建议在这里进行以下建议:https : //coderanch.com/t/464197/java/java/Reading-files-directory-giving-relative为了使此代码在JAR文件中起作用,必须使用getResourceAsStream()。有人可以建议吗?
我正在尝试从RecipeReader.java中访问Recipes.txt,到目前为止,这是我的代码:
Class thisClass = this.getClass();
ClassLoader loader = thisClass.getClassLoader();
URL recipeFileURL = loader.getResource("Recipes.txt");
String path = recipeFileURL.getPath();
path.replaceAll("%20", " ");
BufferedReader input = new BufferedReader(new FileReader(path));
Run Code Online (Sandbox Code Playgroud)
并类似地写入同一文件:
Class thisClass = this.getClass();
ClassLoader loader = thisClass.getClassLoader();
URL recipeFileURL = loader.getResource("Recipes.txt");
String path = recipeFileURL.getPath();
path.replaceAll("%20", " ");
BufferedWriter output = new BufferedWriter(new FileWriter(path));
Run Code Online (Sandbox Code Playgroud)
预先感谢您的帮助!
罗宾
classloader ×10
java ×9
jar ×2
resources ×2
c++ ×1
class ×1
dynamic ×1
eclipse ×1
java-17 ×1
java-module ×1
javafx-8 ×1
jvm ×1
reflection ×1
swing ×1
text-files ×1