[已经解决,但有人回答一下更好]ClassLoader导致,但是为啥。不清楚

本来想写一个自动加载配置文件到类实例里的,直接都没有问题的。

在main方法里面

JFinal.start()在这一句上面。可以正确调用,不报错

afterJFinalStart()里面调用就出异常,百思不得其姐。

希望有人能帮帮我吧。jfinal刚接触不久



加载的代码

private static WebSystemConfigBean bean = new WebSystemConfigBean();
public static void initWebSystemConfigBeanByProp(Properties inprop) {
		try {
			Field[] fields = ClassLoader.getSystemClassLoader().loadClass(WebSystemConfigBean.class.getName())
					.getDeclaredFields();
			for (int i = 0; i < fields.length; i++) {
				fields[i].setAccessible(true);
				
				System.out.println("---"+bean.getClass().getName());
				if (fields[i].getType().getPackage() == null) {
					// 已经是可以直接赋值的属性了
					try {
						fields[i].set(bean, Boolean.parseBoolean(inprop.getProperty("web." + fields[i].getName())));
					} catch (IllegalArgumentException | IllegalAccessException e) {
						e.printStackTrace();
					}
				} else {
					// 说明这还是一个类
					Field[] tfields = fields[i].getType().getDeclaredFields();
					for (int j = 0; j < tfields.length; j++) {
						if (tfields[j].getType() == String.class) {
							tfields[j].setAccessible(true);
							String keyname = "web." + fields[i].getName() + "." + tfields[j].getName();
							try {
								tfields[j].set(fields[i].get(bean), inprop.getProperty(keyname));
							} catch (IllegalArgumentException | IllegalAccessException e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		System.out.println("system ver:" + bean.getSystem().getVer());
		System.out.println("devMode:"+bean.isDevMode());
	}

bean

public class WebSystemConfigBean {
	
	private Db db=new Db();
	private boolean devMode;
	private System system=new System();
	private Smtp smtp=new Smtp();
	private Config config=new Config();

	public Db getDb() {
		return db;
	}
	public void setDb(Db db) {
		this.db = db;
	}
	public boolean isDevMode() {
		return devMode;
	}
	public void setDevMode(boolean devMode) {
		this.devMode = devMode;
	}
	public System getSystem() {
		return system;
	}
	public void setSystem(System system) {
		this.system = system;
	}
	public Smtp getSmtp() {
		return smtp;
	}
	public void setSmtp(Smtp smtp) {
		this.smtp = smtp;
	}
	public Config getConfig() {
		return config;
	}
	public void setConfig(Config config) {
		this.config = config;
	}
	public class Config{
		private String name;
		private String title;
		private String metadescription;
		private String metakeywords;
		private String url;
		private String logourl;
		private String address;
		private String phone;
		private String email;
		private String crrtheme;
		private String certext;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getTitle() {
			return title;
		}
		public void setTitle(String title) {
			this.title = title;
		}
		public String getMetadescription() {
			return metadescription;
		}
		public void setMetadescription(String metadescription) {
			this.metadescription = metadescription;
		}
		public String getMetakeywords() {
			return metakeywords;
		}
		public void setMetakeywords(String metakeywords) {
			this.metakeywords = metakeywords;
		}
		public String getUrl() {
			return url;
		}
		public void setUrl(String url) {
			this.url = url;
		}
		public String getLogourl() {
			return logourl;
		}
		public void setLogourl(String logourl) {
			this.logourl = logourl;
		}
		public String getAddress() {
			return address;
		}
		public void setAddress(String address) {
			this.address = address;
		}
		public String getPhone() {
			return phone;
		}
		public void setPhone(String phone) {
			this.phone = phone;
		}
		public String getEmail() {
			return email;
		}
		public void setEmail(String email) {
			this.email = email;
		}
		public String getCrrtheme() {
			return crrtheme;
		}
		public void setCrrtheme(String crrtheme) {
			this.crrtheme = crrtheme;
		}
		public String getCertext() {
			return certext;
		}
		public void setCertext(String certext) {
			this.certext = certext;
		}
		
	}
	class Smtp{
		private String mail;
		private String host;
		private String port;
		private String username;
		private String password;
		public String getMail() {
			return mail;
		}
		public void setMail(String mail) {
			this.mail = mail;
		}
		public String getHost() {
			return host;
		}
		public void setHost(String host) {
			this.host = host;
		}
		public String getPort() {
			return port;
		}
		public void setPort(String port) {
			this.port = port;
		}
		public String getUsername() {
			return username;
		}
		public void setUsername(String username) {
			this.username = username;
		}
		public String getPassword() {
			return password;
		}
		public void setPassword(String password) {
			this.password = password;
		}
		
	}
	class Db{
		private String dbType;
		private String jdbcUrl;
		private String user;
		private String password;
		public String getDbType() {
			return dbType;
		}
		public void setDbType(String dbType) {
			this.dbType = dbType;
		}
		public String getJdbcUrl() {
			return jdbcUrl;
		}
		public void setJdbcUrl(String jdbcUrl) {
			this.jdbcUrl = jdbcUrl;
		}
		public String getUser() {
			return user;
		}
		public void setUser(String user) {
			this.user = user;
		}
		public String getPassword() {
			return password;
		}
		public void setPassword(String password) {
			this.password = password;
		}
		
	}
	class System{
		private String name;
		private String ver;
		private String description;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getVer() {
			return ver;
		}
		public void setVer(String ver) {
			this.ver = ver;
		}
		public String getDescription() {
			return description;
		}
		public void setDescription(String description) {
			this.description = description;
		}
		
	}
}

异常

java.lang.IllegalArgumentException: Can not set com.luck1go.a_main.WebSystemConfigBean$Config field com.luck1go.a_main.WebSystemConfigBean.config to com.luck1go.a_main.WebSystemConfigBean
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
	at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
	at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)




评论区

zjchxj

2016-10-05 09:44

原来我以为是线程的问题。后经过测试。和这个没有关系的。我直接在 JFinalFilter的init里面调用。还是会报错。

zjchxj

2016-10-05 10:07

最后我自己解决了。我自己把项目导出WAR包到TOMCAT里。发现有找不到类的异常。然后我就试着看看不同的类加载器。最后换成了
Field[] fields = bean.getClass().getClassLoader().loadClass(WebSystemConfigBean.class.getName())
问题虽然已经解决。如果谁能告诉我。为啥在main里直接用 ClassLoader.getSystemClassLoader()可以。在Jfinal里面使用就不行。会更好。

JFinal

2016-10-05 17:57

将这里 Field[] fields = ClassLoader.getSystemClassLoader() 改成如下试试:
Field[] fields = Thread.currentThread().getContextClassLoader()

应该是你的代码使用的是 system 的 classload,而 web 项目使用的是其它的 class load,造成里面加载的类文件不认为是同一个

zjchxj

2016-10-06 17:24

@JFinal 嗯。应该就是这个问题来的。本来弄了一个晚上都没有解决。第二天拿去TOMCAT上面。提示了这个。我就想应该和类加载器有关了。测试果然如此。谢谢回复

JFinal

2016-10-06 21:00

@zjchxj 试过我建议的方法没? 是否可以解决?

热门反馈

扫码入社