Hibernate动态加载时class的加入

2012年12月27日 没有评论

  最近在搞一个模块化的功能,自己写着玩的,最终目的是整合osgi,Hibernate,Spring,Struts等常用框架,并能在模块中动态加入到这些框架中。今天遇到一个Hibernate动态加入时找不到实体类的问题,翻看源码在ReflectHelper中找到答案:

	public static Class classForName(String name) throws ClassNotFoundException {
		try {
			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
			if ( contextClassLoader != null ) {
				return contextClassLoader.loadClass(name);
			}
		}
		catch ( Throwable t ) {
		}
		return Class.forName( name );
	}

在加载类时是通过在当前线程的classLoader中查找类(ClassLoader有隔离机制),所以在动态加载ClassLoader之前需要把当前线程的contextClassLoader设置为我们自己定义的ClassLoader.代码如下:

	Thread.currentThread().setContextClassLoader(loader);//设置当前线程的ContextClassLoader
	ModuleSupporter.hibernateMapping(new File("c:/x3.jar"));

后记:
由于Hibernate本身用了大量反射并且对多个ClassLoade的情况考虑不是很充分,另外动态加入只是加入到Configuration所以需要要单独创建SessionFactory,感觉会浪费资源还有就是多个模块的时候SessionFactory的不同必然会有事务不好控制的问题。

分类: 高级民工 标签: ,

BlazsDS中在MessageInterceptor里获取Flex层方法的注解

2012年10月17日 没有评论

  项目上的一蛋疼的需求,解决方案是需要在flex层进行一次拦截获取到方法上自定义的Annotation的信息来实现这个需求。下面是我分析BlazeDS后得到的获取flex层Method的Annotation的代码。

public class FlexMessageInterceptor implements MessageInterceptor {
 
 
	@Override
	public Message postProcess(MessageProcessingContext arg0, Message arg1,
			Message arg2) {
		return arg2;
	}
 
	@Override
	public Message preProcess(MessageProcessingContext arg0, Message arg1) {
 
 
		if(arg1 instanceof RemotingMessage){
			//记录日志的相关操作
			RemotingMessage remotingMessage = (RemotingMessage)arg1;
			//如果方法名为空则不记录日志,可能是flex自己的client ping等操作
			if(!StringUtil.isBlank(remotingMessage.getOperation())){
				MessageBroker messageBroker = MessageBroker.getMessageBroker("_messageBroker");
				RemotingDestination destination = (RemotingDestination)messageBroker.getService("remoting-service").getDestinations().get(arg1.getDestination());
 
				MethodMatcher methodMatcher = destination.getMethodMatcher();
				FactoryInstance factoryInstance = destination.getFactoryInstance();
				Object instance = factoryInstance.lookup();
				//这个method是cglib代理了的,不知道是不是我用spring整合了BlazsDS的原因
				Method method = methodMatcher.getMethod(instance.getClass(), remotingMessage.getOperation(), remotingMessage.getParameters());
 
				//所以需要用spring提供的一个工具来获取方法的注解
				ModuleLog moduleLog = AnnotationUtils.findAnnotation(method,ModuleLog.class);
 
				//记录日志
				if(moduleLog!=null){
					//做该做的事情
				}
			}
		}
 
		return arg1;
	}
 
}

其余不做过多解释,debug两下基本就可以拿到自己想要的东西。如果疑问留言。

分类: 源码分享, 高级民工 标签:

QQ安全管家安全飞人flash游戏破解

2012年8月22日 5 条评论

  安全飞人游戏是由QQ安全管家奥运会期间推出的一个活动游戏,地址是:http://guanjia.qq.com/act/brand/olympic/?ADTAG=WEB.AOYUN.GJ.GW 。做为flash游戏而言游戏最后得分一般都是会加密后发送到服务器。安全飞人这个游戏也不例外,当然作为flash游戏破解的方式很多,最直接的方式就是反编译找到加密算法直接计算出符合要求的字符串即可。
  安全飞人这个游戏的flash根据检测是通过doSwf加密的,doSwf其加密方式主要有两点:第一点对原始flash中的as代码进行混淆,主要体现在变量名称,类名,方法名的替换,根据破解的流程上看主要是就是把这些名称替换成特殊字符,形成乱码以达到代码不好阅读,不过这种方式通过简单的字符替换就可以让as代码变得易读;第二点是在第一点的基础上对flash进行加壳处理,这个有点类似于一般exe文件的加壳。 针对doswf的破解而言我在网上还没找到现成的工具,不过通过对exe的脱壳的理解,一般来说最后原始文件都将会在内存中被还原。所以抓住这一点就可以在内存中找到原始的flash.下面先介绍一下步骤。
  1.浏览器打开游戏flash。即访问到游戏页面即可。
  2.用winhex打开浏览器进程的内存,直接把整个浏览器分配的内存区域全部dump出来。
  3.用winhex搜索flash文件的特征码。根据adobe的swf文档 描述:

并结合本游戏的flash版本可以得到一个得到特征码:46 57 53 09,直接用winhex搜索特征码,并结合特征码后4字节是文件长度,经过排除和测试后最终可以找到原始的swf文件,通过winhex dump出来。这里所说的原始swf文件其实是被doswf混淆as后的,所以在反编译得到的swf将出现乱码。如图。


阅读全文…

Myeclipse中启动Jetty异常的问题

2012年6月19日 1 条评论

  Jetty7.6.4在MyEclipse8.5中启动后报出下面错误。

java.lang.ClassNotFoundException: org.eclipse.jetty.plus.webapp.Configuration
 at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
 at org.eclipse.jetty.util.Loader.loadClass(Loader.java:92)
 at org.eclipse.jetty.util.Loader.loadClass(Loader.java:71)
 at org.eclipse.jetty.webapp.WebAppContext.loadConfigurations(WebAppContext.java:833)
 at org.eclipse.jetty.webapp.WebAppContext.preConfigure(WebAppContext.java:398)
 at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
 at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
 at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:36)
 at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:183)
 at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:491)
 at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:138)
 at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:142)
 at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:53)
 at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:604)
 at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:535)
 at org.eclipse.jetty.util.Scanner.scan(Scanner.java:398)
 at org.eclipse.jetty.util.Scanner$1.run(Scanner.java:348)
 at java.util.TimerThread.mainLoop(Timer.java:512)
 at java.util.TimerThread.run(Timer.java:462)

解决办法是在项目发布后删除Jetty contexts目录下名为 {项目名}.xml 文件,这样再从Myeclipse中启动jetty就完全正常了,调试什么的都不会出问题。

分类: 高级民工 标签:

让动态加载的jar包相互访问

2012年6月6日 没有评论

  接上一篇文章,如何让加载的jar可以相互访问class的问题,其实方法很简单只用同一个ClassLoader来加载插件的jar即可。这里可以扩展一下URLClassLoader实现。
一个简单的例子:

public class JarLoader extends URLClassLoader {
 
	public JarLoader(){
		super(new URL[]{});
	}
 
	public JarLoader(URL[] urls) {
		super(urls);
	}
 
	/**
	 * 把jar加载到classloader中
	 * @param path jar路径
	 */
	public void addJar(String path){
		try {
			this.addURL(new File(path).toURI().toURL());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}
 
}

通过调用URLClassloader的protected方法addURL即可实现在需要时加载jar到loader中。

分类: 高级民工 标签: