如何注入已运行Java程序,并获取其中的信息

happy4nothing super java  2011-10-18 07:44:09
缘起:
已运行的一Java程序,由于某些原因,该程序的配置文件(.properties文件)被删除了。
现在需要恢复此配置文件,以便此程序可以多次重启。现在已经不敢重启程序了。
(已另外想办法欲从文件系统进行恢复,未果。)

问题:
如何才能获取此程序内存中的信息,将配置信息抓出来呢?

尝试过如下的方法,但由于程序运行在linux系统中,所以未成功。
http://www.blogjava.net/javacap/archive/2007/01/04/91735.html
http://bbs.chinaunix.net/thread-880524-1-1.html

请问各位有何良策,不胜感激!
...全文
337 点赞 收藏 22
写回复
22 条回复
karl1235 2011年10月24日
楼主可以从 那套 解析.properties文件并封装其数据的类下手,访问这些类,把访问到的数据重新写入一个properties文件...
回复 点赞
态度决定品质 2011年10月24日
http://www.zeuux.org/blog/content/3430/

package com.tools;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Set;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import sun.management.ConnectorAddressLink;

import com.sun.tools.attach.AgentInitializationException;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;


public class AttachDemo
{
public void test(String pid) throws NumberFormatException, IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException, MalformedObjectNameException, NullPointerException, InstanceNotFoundException, IntrospectionException, ReflectionException, AttributeNotFoundException, MBeanException
{
String domainName = "Erosa";

String localJmxAddress = ConnectorAddressLink.importFrom(Integer.valueOf(pid).intValue());
if (localJmxAddress == null)
{
VirtualMachine vm = VirtualMachine.attach(pid);
String connectorAddress = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress");
if (connectorAddress == null)
{
String agent = vm.getSystemProperties().getProperty("java.home") + File.separator + "lib" + File.separator + "management-agent.jar";
vm.loadAgent(agent);
connectorAddress = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress");
}
if (connectorAddress == null)
{
System.err.println("Failed to get Local JMX Address by Pid. Exit Without Further Processing.");
System.exit(-1);
}
localJmxAddress = connectorAddress;
}

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
JMXConnector connector = JMXConnectorFactory.newJMXConnector(new JMXServiceURL(localJmxAddress), null);
try
{
connector.connect();
MBeanServerConnection connection = connector.getMBeanServerConnection();
Set<ObjectInstance> set = connection.queryMBeans(new ObjectName(domainName + ":*"), null);
for (ObjectInstance ins : set)
{
System.out.println("==================================================================");

ObjectName name = ins.getObjectName();

System.out.println("MBean : " + name.toString());

MBeanInfo beaninfo = connection.getMBeanInfo(name);
MBeanAttributeInfo[] attributes = beaninfo.getAttributes();
System.out.println("-----------Attributes------------");
for (MBeanAttributeInfo attr : attributes)
{
System.out.println(attr.getName() + ": " + connection.getAttribute(name, attr.getName()));
}
MBeanOperationInfo[] operations = beaninfo.getOperations();
System.out.println("-----------Operations------------");
for (MBeanOperationInfo operation : operations)
{
System.out.println("operation: " + operation.getName() + " " + Arrays.toString(operation.getSignature()));
if (operation.getName().startsWith("dump"))
{
System.out.println(connection.invoke(name, operation.getName(), new Object[0], new String[0]));
}
}
}
System.out.println("exit jmx client.");
}
finally
{
connector.close();
reader.close();
}
}
}
回复 点赞
zhengming_snsoft 2011年10月20日
学习.
回复 点赞
dxqrr 2011年10月20日
mark
回复 点赞
桃园闲人 2011年10月20日
这个貌似要夸进程访问,实现起来很难吧,工具没用过。
回复 点赞
桃园闲人 2011年10月20日
这个貌似要夸进程访问,实现起来很难吧,工具没用过。
回复 点赞
[Quote=引用 14 楼 beowulf2005 的回复:]

引用 8 楼 dracularking 的回复:

找一个什么工具能查看当前内存中指定程序的信息吧
然后把获取到的信息按照配置文件区段加以翻译,只要这些信息不是加密过的


万一改动内存的时候正好GC,后果不堪设想。
[/Quote]
不改动,楼主只是要查询
回复 点赞
nj_dobetter 2011年10月20日
代码注入?这个不好搞吧,JVM进程的中的数据结构很难解析吧
回复 点赞
蒙眼睛的小妖怪 2011年10月19日
好高深的问题,学习
回复 点赞
happy4nothing 2011年10月19日
[Quote=引用 8 楼 dracularking 的回复:]

找一个什么工具能查看当前内存中指定程序的信息吧
然后把获取到的信息按照配置文件区段加以翻译,只要这些信息不是加密过的
[/Quote]
谢谢!
请问有什么工具推荐吗?系统是Red Hat Enterprise Linux 5.x
回复 点赞
chenchenyangll 2011年10月19日
好高级的样子 - -
回复 点赞
找一个什么工具能查看当前内存中指定程序的信息吧
然后把获取到的信息按照配置文件区段加以翻译,只要这些信息不是加密过的
回复 点赞
happy4nothing 2011年10月19日
[Quote=引用 5 楼 yktd26 的回复:]

attach api
这个库不包含在jre的库中,在jdk的lib里tools.jar
[/Quote]
似乎就是这个了。谢谢!
马上试试。。。。。
回复 点赞
happy4nothing 2011年10月19日
[Quote=引用 3 楼 bao110908 的回复:]

难道你们这个配置文件只在部署的环境中存在?
[/Quote]
不好意思,见笑了。我们其实有完整的配置文件的。但在不同的服务器上配置不一样。
另外,备份机制也不完善,导致了这样的结果。。。。:-)
回复 点赞
beowulf2005 2011年10月19日
[Quote=引用 8 楼 dracularking 的回复:]

找一个什么工具能查看当前内存中指定程序的信息吧
然后把获取到的信息按照配置文件区段加以翻译,只要这些信息不是加密过的
[/Quote]

万一改动内存的时候正好GC,后果不堪设想。
回复 点赞
lyhmy 2011年10月19日
太高深了、、、只能围观了解下
回复 点赞
[Quote=引用 10 楼 happy4nothing 的回复:]

引用 8 楼 dracularking 的回复:

找一个什么工具能查看当前内存中指定程序的信息吧
然后把获取到的信息按照配置文件区段加以翻译,只要这些信息不是加密过的

谢谢!
请问有什么工具推荐吗?系统是Red Hat Enterprise Linux 5.x
[/Quote]
看看这个帖子:
http://topic.csdn.net/t/20030922/21/2288646.html
回复 点赞
yktd26 2011年10月18日
attach api
这个库不包含在jre的库中,在jdk的lib里tools.jar
回复 点赞
孟祥月 2011年10月18日
会抓到吗 没有这样的东西吧
回复 点赞
火龙果被占用了 2011年10月18日
难道你们这个配置文件只在部署的环境中存在?
回复 点赞
发动态
发帖子
Java SE
创建于2007-09-28

3.4w+

社区成员

30.7w+

社区内容

Java 2 Standard Edition
社区公告
暂无公告