我使用此代码段来获取文件作为输入流.文件version.txt打包在我应用程序的jar中,位于最上面的文件夹中.
InputStream resource = getClass().getClassLoader().getResourceAsStream("version.txt");
Run Code Online (Sandbox Code Playgroud)
这几乎在所有时间都有效.但是对于一个用户来说,它正在拾取另一个版本.txt,这不在我的jar中.如何确保加载我jar中的特定version.txt文件?
假设我使用Groovyc编译了一个Groovy脚本,它在文件系统中生成了一个或多个.class文件.从Java应用程序中,如何动态地将这些类添加到类路径中以加载它们并调用它们的方法?目标是预编译Groovy脚本并将它们存储到数据库中,因此可以从脚本的编译版本执行评估.
在用于加载类的父委托模型中,我知道在父类上调用loadclass(),一直到类加载器层次结构的顶部(假设没有加载类).此时调用最顶层的父类加载器的findClass.如果找不到这个类,控件如何转移到下一个类加载器的findClass方法?
我的Java应用程序中有插件系统.是否可以动态地将JAR/Java类加载到您的应用程序中,或者我是否必须将这些JAR/Java类包含到我的应用程序中?
我的想法是将插件加载到应用程序然后调用此类的接口方法,而无需重新启动Java应用程序.这有可能甚至是明智的吗?
我使用Zend框架开发项目,我遇到了以下问题.我正在使用他们的zf.sh脚本生成的Zend框架MVC文件夹结构.
我的库文件夹有Zend库文件夹,它的类可以在应用程序内正常调用.我在我的库中为我的类创建了另一个文件夹.这是现在的文件夹结构:
我的项目
| _application
| _docs
| _public
| _library
| _Zend
| _Buyers
| _Donations.php
| _scripts
我将我的Donation类命名为"Buyers_Donations"作为Zend框架命名约定.
当我尝试在我的控制器中使用这个类时
$obj= new Buyers_Donation();
Run Code Online (Sandbox Code Playgroud)
它给出了一个错误,无法在控制器内找到类Buyers_Donation.
但是当我在我的Bootstrap中添加以下行时,它工作正常:
$loader = Zend_Loader_Autoloader::getInstance();
$loader->setFallbackAutoloader(true);
$moduleLoder = new Zend_Application_Module_Autoloader(
array(
'namespace'=>'',
'basePath'=>dirname(__FILE__)
));
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下实际发生了什么以及模块自动加载器有什么用处,虽然我的应用程序中没有任何模块?
我看过一篇关于Class.forName是否可以在这里返回null的帖子,每个人似乎认为它不能(或不会).但是,它使用以下代码为我返回null:
public void init() {
File binDriectory = new File("./bin/dft");
String[] files = binDriectory.list();
for (String file : files) {
if (file.endsWith(".class")) {
if (file.indexOf("DataReader") > 0) {
//strip off the ".class"
String className = file.substring(0, file.indexOf(".class"));
try {
//load the class
Class readerclass = Class.forName("dft." + className);
//get the file extension of the file type this class deals with
/* NullPointerException thrown here in call to getMthod() */
Method getExtensionMethod = readerClass.getMethod("getFileExtension", null);
String extension = (String) …Run Code Online (Sandbox Code Playgroud) 我们在克服Java webstart的混合代码错误时遇到了困难.总之,我们有我们的主要JNLP文件,我们已经签署了它直接加载的所有代码.我们已将all-permissions选项添加到主JNLP中.它加载的主类也来自一个签名的jar.
当主要类开始时,它会触发一些需要加载从JNLP B中提取的未签名资源的东西.JNLP B的资源都没有签名,也不需要任何特殊权限.
所有已签名的代码都是基于Oracle的混合代码文档设置的,并且jar文件在签名之前已经设置了"Trusted-Library:true"的清单.
当尝试通过签名代码加载未签名的代码时,我们得到一个类未找到错误,如下所示:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: org/some/external/package/that/is/not/signed
at org.our.signed.package.main(Main.java:87)
... 9 more
Caused by: java.lang.ClassNotFoundException: org.some.external.package.that.is.not.signed
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 10 more
Run Code Online (Sandbox Code Playgroud)
以下是JNLP中的情景:
JNLP答:(总结)
<jnlp spec="1.5+" codebase="...." href="......">
<information>
...etc
</information>
<security>
<all-permissions/> …Run Code Online (Sandbox Code Playgroud) 我知道规范确切地定义了它,但无法得到这个的原因:
A class space is then all classes reachable from a given bundle’s class loader.
Thus, a class space for a given bundle can contain classes from:
• The parent class loader (normally java.* packages from the boot class path)
• Imported packages
• Required bundles
• The bundle's class path (private packages)
• Attached fragments
Run Code Online (Sandbox Code Playgroud)
我们假设:
new aX()将从另一个bundle加载该类.
导入的类优先于bundle类的原因是什么?它只是java层次类加载策略的后续延续吗?
比方说,我有两个类加载器,x并且y,用于装载ClassX和ClassY分别,以及它们的依赖关系.应用程序中的其他所有内容都使用默认的类加载器加载.
现在假设ClassX并ClassY共享一个依赖项,ClassZ.
如果主应用程序也依赖于ClassZ(无论它是否实际加载了类),我的假设是x/ y将根本不会使用/ 来解决这个问题,因为默认的类加载器应该能够找到它.(如果我错了,请纠正我.)
现在,我的主要问题是什么,如果只发生x和y可以找到ClassZ:如果同时ClassX和ClassY引用它,将它装入两次(即浪费在PermGen的两倍的空间),或者是Java的足够聪明来检测,它是完全相同的类,加载由两个不同的类加载器,只在内存中保留一个副本?
是否可以在运行时通过Maven加载远程工件,例如使用特定的(Maven)ClassLoader?
对于我的用例,遗留软件使用URLClassLoader在启动测试框架期间提取包含一些资源文件的JAR.
问题是我们目前只使用指向存储库的固定URL而根本不使用Maven工件解析.
将它添加到项目依赖项是没有选择的,因为我们想要从外部配置文件引用特定版本(使用不同版本的打包用例运行测试框架而不更改代码).
我希望你得到我想要达到的目标 - 它不一定是最漂亮的解决方案,因为我们目前依赖于固定的URL模式,我想依赖于本地maven设置.
classloader ×10
java ×8
classpath ×1
code-signing ×1
delegation ×1
groovy ×1
jnlp ×1
maven ×1
module ×1
osgi ×1
php ×1