I find two ways to get all GarbageCollectorMXBeans from JVM,
First
ManagementFactory.getGarbageCollectorMXBeans() which described from JAVA API
Second
List<GarbageCollectorMXBean> beans = new ArrayList<GarbageCollectorMXBean>();
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName gcName = new ObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",*");
for (ObjectName name : server.queryNames(gcName, null))
{
GarbageCollectorMXBean gc = ManagementFactory.newPlatformMXBeanProxy(server, name.getCanonicalName(), GarbageCollectorMXBean.class);
beans.add(gc);
}
I want to know any differences between these two?
There is no difference. The first variant is just a shortcut for the second one.
Related
I'm trying to query again a particular dns server both in linux shell using digg and using Java.
The dig command works. but the java way doesn't. what's wrong?
dig #dns.nic.it test.it
;; QUESTION SECTION:
;test.it. IN A
;; AUTHORITY SECTION:
test.it. 10800 IN NS dns2.technorail.com.
test.it. 10800 IN NS dns.technorail.com.
test.it. 10800 IN NS dns3.arubadns.net.
test.it. 10800 IN NS dns4.arubadns.cz.
java way
public static void rootDNSLookup(String domainName) throws NamingException{
String server="dns://dns.nic.it";
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
env.put("java.naming.provider.url", server);
DirContext ictx = new InitialDirContext(env);
Attributes attrs = ictx.getAttributes(domainName, new String[] {"A", "AAAA", "NS", "SRV"});
System.out.println(attrs);
NamingEnumeration e = attrs.getAll();
while(e.hasMoreElements()) {
Attribute a = e.next();
System.out.println(a.getID() + " = " + a.get());
}
}
java prints:
No attributes
The best way to go is to use the library dnsjava.
The particular class you are looking for is SimpleResolver. It has two constructors. When used with no parameters it will use the system's DNS settings. If you provide an IP address it will force that as the DNS server.
You can find a great example of usage here: dnsjava Examples.
Don't try and get all attributes at the same time.
Use:
Attributes attrs = ictx.getAttributes(domainName, new String[] {"A"});
Use a String array that contains all attributes you want and iterate over the call passing in the attribute.
String[] attributes = {"A", "AAAA", "NS", "SRV"};
for (String attribute : attributes) {
...
Attributes attrs = ictx.getAttributes(domainName, new String[] {attribute});
...
}
I am writing a Java class to browse a Tibco EMS JMS server and show all queues. I'm able to connect without issues and browse specific queues but I am looking for a way to return a list of all queues (with queue depth if possible). I'm not if there is a specific EMS API to use so I am using standard JMS.
I've tried the following code to do a reverse JNDI lookup but it is failing.
NamingEnumeration<?> queues = context.list("");
List<String> availableQueuesNames = new ArrayList<String>();
while (queues.hasMoreElements()) {
NameClassPair element = (NameClassPair) queues.nextElement();
availableQueuesNames.add(element.getName());
}
Which throws this error:
javax.naming.OperationNotSupportedException: Not supported
at com.tibco.tibjms.naming.TibjmsContext.list(TibjmsContext.java:1018)
at com.tibco.tibjms.naming.TibjmsContext.list(TibjmsContext.java:484)
at javax.naming.InitialContext.list(Unknown Source)
I did some digging and it seems Tibco EMS does not support looking into the JNDI like this. Is there another way to accomplish this?
Using the tibjmsServerAdministrator.java same class provided with Tibco as a guide (and the addAdmin() method), I was able to write code to list all queues:
Map<String, TibjmsAdmin> map = new HashMap<String, TibjmsAdmin>();
addAdmin(txtServer.getText(), txtUser.getText(), txtPassword.getText(), map);
_admin = new TibjmsAdmin[map.size()];
map.values().toArray(_admin);
QueueInfo[] info = _admin[0].getQueues(null);
for (int i = 0; i < info.length; i++) {
String queueName = info[i].getName();
if (!queueName.startsWith("$") && !queueName.startsWith(">")) {
queues.add(queueName + ", 0");
}
}
I'm not sure about Tibco details, but maybe it would work with listBindings instead of list?
I have done the same thing in a generic way like this:
List<Queue> out = new ArrayList<>();
scanJndiForQueues(out, "");
...
private void scanJndiForQueues(List<Queue> out, String path) throws NamingException {
InitialContext context = new InitialContext();
Object resource = context.lookup(path);
if (isSubContext(resource)) {
NamingEnumeration<Binding> list = context.listBindings(path);
while (list.hasMoreElements()) {
Binding binding = list.nextElement();
scanJndiForQueues(out, path + "/" + binding.getName());
}
} else if (resource instanceof Queue) {
out.add((Queue) resource);
} // else ignore Topics
}
private boolean isSubContext(Object object) {
return javax.naming.Context.class.isAssignableFrom(object.getClass());
}
Don't know why you need to list all the EMS queues, but you can achieve this (and many other things) with the GEMS tool.
Search for it at tibcommunity (you will need an account), or you can download the last version directly from here.
I'm trying to run:
Map<String, String> environmentProperties = new HashMap<String, String>();
environmentProperties.put("java.naming.security.authentication", "simple");
environmentProperties.put("java.naming.ldap.attributes.binary", "tokenGroups objectSid");
LdapContextSource contextSource = new LdapContextSource();
contextSource.setAnonymousReadOnly(false);
contextSource.setPooled(false);
contextSource.setUserDn("CN=Administrator,CN=Users,DC=someDomain,DC=com");
contextSource.setPassword("password");
contextSource.setUrls(new String[]{"ldap://url.goes.here"});
contextSource.setBaseEnvironmentProperties(environmentProperties);
contextSource.setDirObjectFactory(null);
contextSource.afterPropertiesSet();
final SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
ContextExecutor contextExecutor = new ContextExecutor() {
public Object executeWithContext(DirContext ctx) throws NamingException {
EventDirContext ectx = (EventDirContext) ctx.lookup("CN=Users,,DC=someDomain,DC=com");
ectx.addNamingListener("", "(cn=*)", searchControls, new LDAPChangeListener());
return null;
}
};
LdapTemplate ldapTemplate = new LdapTemplate(contextSource);
ldapTemplate.setIgnorePartialResultException(true);
ldapTemplate.executeReadOnly(contextExecutor);
but, the first message my listener gets is:
javax.naming.OperationNotSupportedException: [LDAP: error code 12 - 00000057: LdapErr: DSID-0C090753, comment: Error processing control, data 0, v1db1 ]; remaining name ''
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3127)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3013)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2820)
at com.sun.jndi.ldap.LdapNamingEnumeration.getNextBatch(LdapNamingEnumeration.java:129)
I also ran this code I found here that's supposed to verify that my AD supports persistent search, and the result was true.
static boolean isPersistentSearchSupported(LdapContext rootContext)
throws NamingException {
SearchResult rootDSE;
NamingEnumeration searchResults;
Attributes attrs;
NamingEnumeration attrEnum;
Attribute attr;
NamingEnumeration values;
String value;
String[] attrNames = { "supportedControl" };
SearchControls searchControls = new SearchControls();
searchControls.setCountLimit(0); // 0 means no limit
searchControls.setReturningAttributes(attrNames);
searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);
// search for the rootDSE object
searchResults = rootContext.search("", "(objectClass=*)",
searchControls);
while (searchResults.hasMore()) {
rootDSE = (SearchResult) searchResults.next();
attrs = rootDSE.getAttributes();
attrEnum = attrs.getAll();
while (attrEnum.hasMore()) {
attr = (Attribute) attrEnum.next();
values = attr.getAll();
while (values.hasMore()) {
value = (String) values.next();
if (value.equals("1.2.840.113556.1.4.528"))
return true;
}
}
}
return false;
}
what do I need to do to start getting events from AD?
According to the documentation, the scope can't be Subtree and the search filter must be (objectClass=*) for a persistent search.
UPDATE:
I found this: https://forums.oracle.com/thread/1157474?tstart=0
It basically says that AD does not support this, and that there’s no way I can make the above code work.
However, it does give out 2 different ways of getting such notifications from AD:
Using DirSync- I tried the attached code, and it did not work, but did not continue investigating from the reasons that will be listed in the end of this post.
Using LDAP Notifications (https://forums.oracle.com/message/4698114 )- this code worked, however, it only returns results for created / changed events, it will not notify once an object gets deleted, and there’s no way of getting it with this method since the search filter cannot be changed, because any other filter will not work. So it did not fit my purposes, but maybe someone else finds it useful.
I thought DirSync might be the only solution possible for me, if any.
However, it should be noted that DirSync has the following limitations:
The DirSync control can only be used by a highly privileged account, such as a domain administrator.
The DirSync control can only monitor an entire naming context. You cannot limit the scope of a DirSync search to monitor only a specific subtree, container, or object in a naming context.
I hope this information will help someone else in the future.
I would like to add some additional information on this topic since I have done research on this topic couple years ago.
The NamingListener capability provided by JNDI. If you try to register a NamingListener on any LDAP server, that particularly server must support the 'Persistent Search' extension. The Persistent Search extension has always been in IETF draft stage therefore there's no official RFC# associate with it.
Not a lot of LDAP server support this extension. The last time I researched on this topic was 2008 and the LDAP servers that support persistent search extension were 389 Directory Server, Oracle Internet Directory (OID) and OpenDS (now known as OpenDJ).
http://www-archive.mozilla.org/directory/ietf-docs/draft-smith-psearch-ldap-01.txt
http://www.redhat.com/archives/fedora-directory-users/2008-May/msg00120.html
I'm implementing a servlet as a JMX manager that runs in the same instance of Tomcat that all of the monitored servlets are running in. I can see the data of the monitored servlets when I open JConsole. From within my manager servlet I can enumerate all of the available standard MBeans, including the ones I've created in the monitored servlets, using this code like this:
JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi://localhost:1099/jndi/rmi://localhost:1099/jmxrmi" );
mConnector = JMXConnectorFactory.connect( url );
mMBSC = mConnector.getMBeanServerConnection();
mObjectName = new ObjectName( "com.blahCompany.blah.blah:type=BlahBlah" );
// just looking for one specific bean
Set<ObjectName> myMbean = mMBSC.queryNames( mObjectName, null );
if( myMBean.size() == 1 ) // I know it exists
{
MBeanInfo mbeanInfo = mMBSC.getMBeanInfo( <ObjectName extracted from Set> );
MBeanAttributeInfo[] mbeanAttributeInfos = mbeanInfo.getAttributes();
for( MBeanAttributeInfo attribInfo : mbeanAttributeInfos )
{
if( attribInfo.isReadable() )
{
String attribName = attribInfo.getName();
String attribReturnType = attribInfo.getType();
// The data's somewhere ... where????
// In the MBeanInfo?
// In the MBeanAttributeInfo??
}
}
}
The problem is I don't know how to actually extract the data from these MBeans. The answer must be godawful obvious because no one else seems to have asked, but I do have a gift for overlooking the obvious. Your help will be gratefully appreciated.
Bill
All you need to do is something like the below:
Object value = mMBSC.getAttribute(objectName, attributeName);
Or create a proxy object that gets an instance of the MBean interface and allows you to access it that way. A tutorial on how to do this is here: http://docs.oracle.com/javase/tutorial/jmx/remote/custom.html
One note, this is assuming a remote connection, but from your question it seems your are accessing the beans locally? If that is the case then you can use platform.getMBeanServer() to get access to the MBeanServer more directly. E.g. MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
If I look up a IP address from a DNS name as follows:
InetAddress inetAddress = InetAddress.getByName(name);
String address = inetAddress.getHostAddress();
Can I find out which nameserver gave me the information?
I'm not sure if this is what you want, but there's a DNSJava library which provides DNS functionality in Java. Perhaps you can use this to either get a better understanding of your issues, or to implement a particular solution ? Like I say, not a perfect match for you, but perhaps helpful.
For a given InetAddress, try the following:
// get the default initial Directory Context
InitialDirContext idc = new InitialDirContext();
// get the DNS records for inetAddress
Attributes attributes = idc.getAttributes("dns:/" + inetAddress.getHostName());
// get an enumeration of the attributes and print them out
NamingEnumeration attributeEnumeration = attributes.getAll();
System.out.println("-- DNS INFORMATION --");
while (attributeEnumeration.hasMore()) {
System.out.println("" + attributeEnumeration.next());
}
attributeEnumeration.close();
Adapt it to pick up what you're looking for.
you need an Naming Context. Optional you can Specify the DNS Server.
And even then you need to select that you are looking for. Here is an example.
final String ADDR_ATTRIB = "A";
final String[] ADDR_ATTRIBS = {ADDR_ATTRIB};
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
idc = new InitialDirContext(env);
env.put(Context.PROVIDER_URL, "dns://"+dnsServer);
final List<String> ipAddresses = new LinkedList<>();
final Attributes attrs = idc.getAttributes(hostname, ADDR_ATTRIBS);
final Attribute attr = attrs.get(ADDR_ATTRIB);
if (attr != null) for (int i = 0; i < attr.size(); i++) ipAddresses.add((String) attr.get(i));