Перезагрузка класса после его модификации

0
06 июн 2016 11:35
У меня есть сервер
в котором крутится бесконечный цикл
внутри цикла есть вот такой код

			while (isRun() == 1){
				System.out.print("wait accept.....");
				mClient = mServerSocket.accept();
				System.out.println("done accept");
				
				mFromClient = new BufferedReader(new InputStreamReader(mClient.getInputStream()));
				mToClient = new PrintStream(mClient.getOutputStream());
				String messageFromClient;
				String messageToClient;
				
				messageFromClient = mFromClient.readLine();
				if (messageFromClient == null){
					break;
				}

				scip sIn = new scip();
				sIn.parseResponse(messageFromClient);

				//----------------------------------------
				Method method = null;
				Class cls = null;
				Object obj = null;
				try {
					System.out.println("load class db.CheckCard");
					cls = Class.forName("db.CheckCard");
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
					break;
					//return;
				}
				
				try {
					System.out.println("new instance db.CheckCard");
					obj = cls.newInstance();
				} catch (InstantiationException | IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return;
				}
				
				Object returnVal = null;
				try {
					System.out.println("run methods db.CheckCard");
					method = cls.getDeclaredMethod("checkScip", scip.class);
					method.setAccessible(true);
					returnVal = method.invoke(obj, sIn);
					method = cls.getDeclaredMethod("closeDB");
					method.setAccessible(true);
					method.invoke(obj);
				} catch (NoSuchMethodException | SecurityException | IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				scip sOut = (scip) returnVal;
				//-----------------------------------
				
				//CheckCard cc = new CheckCard();
				//scip sOut = cc.checkScip(sIn);
				//cc.closeDB();
				
				System.out.println(messageFromClient);
				messageToClient = sOut.getRequest();
				System.out.println(messageToClient);
				mToClient.println(messageToClient);
			}


Собственно говоря я считал что при каждом выполнении цикла класс db.CheckCard должен перезагружаться
и таким образом если я хочу на лету модифицировать класс
то могу просто подкладывать новый скомпилированный db.CheckCard
и он будет уже его использовать
на практике полное ощущение того что он использует старый instance класса

не подскажите куда копать?

Ответов: 1

1
06 июн 2016 17:43
Класс грузится класслоадером 1 раз при первом использовании и далее ни при каких условиях в этом класслоадере не перезагружается.

Класс может быть заново загружен другим класслоадером, если тот не связан с первым как parent-child.

Класс можно redefine'ить через instrumentation API или через дебаггер. В первом случае надо сделать java agent и в нем будет доступен АПИ. При redefine нельзя добавлять/удалять поля методы.

Работающее решение - использовать jrebel: https://zeroturnaround.com/software/jrebel/
Модераторы: Нет
Сейчас эту тему просматривают: Нет