刚买了一只加密狗,厂商接供了访问该狗的java类,该类使用了JNI接口,故无法改变该类的类名和包名。该类没有包名,即默认无包名的类,必须放到程序运行的根目录下。现在我使用JDK1.5,我所有的类若使用厂商提供的类访问狗,也必须不能带包名,即放到程序运行的根目录下,无法通过import导入没有包名的类。难道在JAVA中一个类若没有包名,就不能被有包名的类导入或使用吗?为了使用没有包名的类,必须我其它的类也不能有包名?不这样做就通不过编译,这是怎么回事?
注:厂商提供的无包名类为public类型。
注:厂商提供的无包名类为public类型。
解决方案 »
- 设计模式的误区,Java程序员对设计模式的诋毁及滥用
- 求大神们指点,急
- 回帖中引用功能实现--java正则表达式如何实现
- 问三个问题,谢谢回答!!
- 使用PooledExecutor后,进程总是莫名其妙的死掉,高手看看。。。
- 如何让一个虚拟机实例里的运行的应用程序所调用的类运行在另一个虚拟机实例里???
- 关于设置JOPtionPane的字体的问题,如何设置字体和切换中/英文呢?
- 求救:jTree的一问!
- jCreator LE v3.10 版本的,为什么不能自动显示方法
- 请帮忙!谢谢!
- 谁知道数学函数ln(x)java里怎么表示吗,就是log已e为底的那个阿
- 大来给我说说类包的问题吧.大虾不要不理我呀!!
这样的语法根本通不过编译。
不使用import的话就必须放到跟JavaClass类同样的根目录下,变成无名包的类。
所有可能的方法我都试过了。
Class.forName("NoPackage").newInstance();不过这样也很麻烦的
这个厂商也太不地道了,连个包名都没有,何况包名还可以顺便给他自己打广告。你应该找厂商更改,否则你就退货。你也可以全部翻编译,然后移动到一个包下面去。
import *.class太麻烦
厂商说我如果订购500个以加密狗上的话,可以经我重新编译一个类,加上包名。太不象话了
厂商说我如果订购500个以上加密狗上的话,可以给我重新编译一个类,加上包名。
退货,又花钱又麻费,没准还退不掉,怎么也是我赔本买卖。
如果你想把类B放在C:/dog这个文件夹中,类A不在C:/dog中,也想顺利访问到类B,那么你就把C:/dog放到你的classpath中,这样C:/dog就会成为默认包的位置了。
public class Dog implements yourpackage.IDog {
public void method1() {
...
} public int method2() {
...
return xxx;
} ...
}
//IDog.java
package yourpackage;public class interface IDog {
public void method1();
public int method2();
...
}
//DogFactory.java
package yourpackage;public class DogFactory {
private static IDog dog = null; public static IDog createDog() {
if (dog == null) {
try {
dog = (IDog)Class.forName("Dog").newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
return dog;
}
}其它地方用的时候调用 DogFactory.createDog()来得到IDog的实例, 调用相应的方法。
public class interface IDog -> public interface IDog
dog = (IDog)Class.forName("Dog").newInstance();
上面这两句是通不过的。
因为厂商的Dog类中的所有方法是native类型,还包括许多public类型常量字段,不可以映射到非native的接口。
用native方法实现接口是可以的, 这我两年前就试过了,刚才又试了一下,结果还是一样。>>>"这是因为一个含有JNI调用的类,其所有方法类型包括非私有字段变量都是不能改变的。"
没有这回事。只要这个类的包名、类名以及native方法的声明没有变化,对应的dll就不需要重新编译,其他的非native方法和字段可以随便改,这个我也试过的。至于那些public类型常量字段,完全可以从Dog类里面删掉,提到IDog接口里面,不会影响到Dog类的编译,不信的话你可以自己试一下。使用这种方法还有一个好处,就是如果你的IDE支持重构的话,就可以使用Extract Interface 功能自动从Dog类生成IDog接口,连复制修改代码的手续都省了。不过楼主你既然不怕麻烦,自己已经用反射的方法实现了,那就算了。加密狗的厂商不愿意给你加包名就是因为包名改了,对应的.h文件需要重新生成,对应的.c文件里的所有函数名也都需要改,然后还要重新编译dll。而且为了支持其他不想加包名的客户,原来的java文件、.h文件和.c文件都还要保留,这样就需要维护两套源程序。要是我大概也会觉得麻烦, 不过那也没办法,谁让他们早点没考虑到这个问题呢。
后面是实验用到的所有文件,楼主你要是有兴趣就自己试一下,没兴趣的话就算了,反正不管简单办法还是苯办法,达到目的就行。
public class Dog implements yourpackage.IDog {
//这两个常量移到IDog接口里去了
//public static final int TEST1 = 100;
//public static final String TEST2 = "Hello"; static {
try
{
System.loadLibrary("dog");
}
catch (Exception e)
{
e.printStackTrace();
}
}
//native 方法也可以实现接口
public native void method1();
public native int method2(); //底下这些字段和构造方法是在dll生成之后新加的,并没有影响到native方法的调用
/////////////////////////////////////////
private int a;
private String b; public Dog()
{
System.out.println("Create new Dog");
a = 1;
b = "test";
System.out.println("TEST1=" + TEST1);
System.out.println("TEST2=" + TEST2);
}
}//IDog.java
package yourpackage;public interface IDog {
public static final int TEST1 = 100;
public static final String TEST2 = "Hello"; public void method1();
public int method2();
}//DogFactory.java
package yourpackage;public class DogFactory {
private static IDog dog = null; public static IDog createDog() {
if (dog == null) {
try {
dog = (IDog)Class.forName("Dog").newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
return dog;
}
}//TestDog.java
package yourpackage;public class TestDog
{
public static void main(String[] args)
{
IDog dog = DogFactory.createDog();
dog.method1();
System.out.println(dog.method2());
}
}/* Dog.h */
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Dog */#ifndef _Included_Dog
#define _Included_Dog
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Dog
* Method: method1
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Dog_method1
(JNIEnv *, jobject);/*
* Class: Dog
* Method: method2
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_Dog_method2
(JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif
/* Dog.c */
#include "jni.h"
#include "Dog.h"JNIEXPORT void JNICALL Java_Dog_method1(JNIEnv* env, jobject obj)
{
printf("method1 invoked\n");
}
JNIEXPORT jint JNICALL Java_Dog_method2(JNIEnv* env, jobject obj)
{
printf("method2 invoked\n"); return 999;
}
我回去试了一下,确实含有native接口的方法的类也能造型到接口。这个方法解决无名包的导入问题可能是最简单的解决办法了吧。谢谢指点。