My question is similar to the one in this 2 year old post:
Is there a way to handle dynamic connexion to datasource with quarkus?
I have say 10 different DBs, all of them are in Postgres and they even have the same user and password, so the only thing that changes is the database name.
I have an endpoint similar to /{databasename}/customers, so I'd like to be able to retrieve the list of customers from the database name that is passed as a parameter.
I know I might try to write an extension to do that, but I have not been able to do so, and I'm not sure that I really want to modify the framework to do this.
I'd like to understand what the options are to do something like this
I thought that something similar to the code snippet below might help to dynamically connect to a DS, but there's not way for me to make it work because this is a way to programmatically set up the connection once the application is starting up:
AgroalDataSourceConfigurationSupplier configuration = new AgroalDataSourceConfigurationSupplier()
.dataSourceImplementation( AgroalDataSourceConfiguration.DataSourceImplementation.AGROAL )
.metricsEnabled( false )
.connectionPoolConfiguration( cp -> cp
.minSize( 5 )
.maxSize( 20 )
.initialSize( 10 )
.connectionValidator( AgroalConnectionPoolConfiguration.ConnectionValidator.defaultValidator() )
.acquisitionTimeout( Duration.ofSeconds( 5 ) )
.leakTimeout( Duration.ofSeconds( 5 ) )
.validationTimeout( Duration.ofSeconds( 50 ) )
.reapTimeout( Duration.ofSeconds( 500 ) )
.connectionFactoryConfiguration( cf -> cf
.jdbcUrl( "jdbc:postgresql://localhost/quarkus_test3" )
// .connectionProviderClassName( "org.h2.Driver" )
.autoCommit( false )
.jdbcTransactionIsolation( AgroalConnectionFactoryConfiguration.TransactionIsolation.SERIALIZABLE )
.principal( new NamePrincipal( "postgres" ) )
.credential( new SimplePassword( "postgres123" ) )
)
);
try ( AgroalDataSource dataSource = AgroalDataSource.from( configuration ) ) {
Connection connection = dataSource.getConnection();
connection.close();
} catch ( SQLException e ) {
System.out.println( "Oops! " + e.getMessage() );
}
Related
I am using the verbosegc to capture some data and try to analyze the memory usage of my application.
I have a module that will pulling data from database or third party and put it into a list object then only return to front end for display.
When I choose the date to be date range, it will pull the data from database.
When I choose the date to be today date, then my application will send a request to MQ server, and the MQ server will response my application with xml message. The I will use Apache camel library to handle it.
Here is my verbosegc screen shot when pulling data from database:
As you can see, everytime when I trigger the search function, the memory usage will increase, and then drop back. So this is normal, and also what I expected.
And this is the verbosegc screen shot when pulling data from third party.
As you can see, after the memory increase, it will will horizontal there for a period, and then only drop back.
I suspect that the org.apache.camel.Exchange or org.apache.camel.Message or those object in Apache will holding the memory for longer time.
Here is some of my code to handle the xml message from third party:
/**
* Camel Exchange producer template
*/
protected ProducerTemplate< Exchange > template;
#SuppressWarnings("unchecked")
private < T > T doSend(final Object request, final String headerName,
final Object headerObject,
final SendEaiMessageTemplateCallBack callback)
throws BaseRuntimeException {
log.debug( "doSend START >> {} ", request );
if ( this.requestObjectValidator != null
&& requestObjectValidator
.requiredValidation( requestObjectValidator ) ) {
requestObjectValidator.validateRequest( request );
}
final Exchange exchange = template.request( to, new Processor( ) {
public void process(final Exchange exchange) throws Exception {
exchange.getIn( ).setBody( request );
if ( headerName != null && headerObject != null ) {
exchange.getIn( ).setHeader( headerName, headerObject );
}
}
} );
log.debug( "doSend >> END >> exchange is failed? {}",
exchange.isFailed( ) );
Message outBoundMessage = null;
if ( callback != null ) {
// provide the callBack method to access exchange
callback.exchangeCallBack( exchange );
}
if ( exchange.isFailed( ) ) {
failedHandler.handleExchangeFailed( exchange, request );
} else {
outBoundMessage = exchange.getOut( false );
}
// handler outbound message
if ( this.outboundMessageHandler != null ) {
this.outboundMessageHandler.handleMessage( outBoundMessage );
}
if ( outBoundMessage != null ) {
if ( outBoundMessage.getBody( ) != null ) {
log.debug( "OutBoundMessage body {}", outBoundMessage.getBody( ) );
}
return (T) outBoundMessage.getBody( );
} else {
return null;
}
}
Because of this, my application was hitting Out Of Memory Exception. I am not sure is it because of Apache Camel library or not, kindly advise.
Other than that, when I open the heapdump file, there is 52% complain on the com/ibm/xml/xlxp2/scan/util/SimpleDataBufferFactory$DataBufferLink
And the other are complain on the "Java heap is used by this char[] alone", which is some sub category under DataBufferLink as well.
I google on this, all is talking about the xml message too large.
I have no idea on which way or which direction I should continue to troubleshoot, can kindly advise on this?
FYI, I am using camel-core-1.5.0.jar
I'm integrating OpenSAML 3.3 in my application, and instead of hard-coding all the urls etc, I would like to be able to use the configuration XMLs.
I was given such an XML file for a adfs instance, it is 'FederationMetadata.xml'
This is the snippet I used to read it:
InitializationService.initialize();
FilesystemMetadataResolver idpMetaDataProvider = new FilesystemMetadataResolver( new File("/home/raudenaerde/sso/FederationMetadata.xml") );
idpMetaDataProvider.setRequireValidMetadata(true);
idpMetaDataProvider.setParserPool(new BasicParserPool());
idpMetaDataProvider.initialize();
However, this gave me this error:
> Exception in thread "main"
> net.shibboleth.utilities.java.support.component.ComponentInitializationException:
> Component identifier can not be null
Using an github project (https://github.com/coveo/saml-client) that uses OpenSAML 2.6.4 I had no problems reading it, but I'd like to stick with the newest version 3.3.
Am I missing some basic set-up?
There are 2 things that needed to be fixed:
In OpenSaml v3 many class instances are required to have an ID, setId(String) must be called before initialize()
The BasicParserPool needs to be initialized as well.
Complete working code:
InitializationService.initialize();
FilesystemMetadataResolver idpMetaDataProvider = new FilesystemMetadataResolver( new File( "/home/raudenaerde/sso/FederationMetadata.xml" ) );
idpMetaDataProvider.setRequireValidMetadata( true );
idpMetaDataProvider.setId( "myId" );
BasicParserPool pool = new BasicParserPool();
pool.initialize();
idpMetaDataProvider.setParserPool( pool );
idpMetaDataProvider.initialize();
for ( EntityDescriptor idpEntityDescriptor : idpMetaDataProvider )
{
System.out.println( idpEntityDescriptor.getID() );
for ( SingleSignOnService sss : idpEntityDescriptor.getIDPSSODescriptor( SAMLConstants.SAML20P_NS ).getSingleSignOnServices() )
{
if ( sss.getBinding().equals( SAMLConstants.SAML2_REDIRECT_BINDING_URI ) )
{
System.out.println( sss.getLocation() );
}
}
for ( ArtifactResolutionService ars : idpEntityDescriptor.getIDPSSODescriptor( SAMLConstants.SAML20P_NS ).getArtifactResolutionServices() )
{
if ( ars.getBinding().equals( SAMLConstants.SAML2_SOAP11_BINDING_URI ) )
{
System.out.println( ars.getLocation() );
}
}
}
I am integrating window based application with java application and want to capture window events in java.
I found in google J-Interop is the library thorugh this can be achived.
i did some POC wih below code but facing issue while locating the service i.e WbemScripting.SWbemLocator
import java.io.IOException;
import java.util.logging.Level;
import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.common.JISystem;
import org.jinterop.dcom.core.JIComServer;
import org.jinterop.dcom.core.JIProgId;
import org.jinterop.dcom.core.JISession;
import org.jinterop.dcom.core.JIString;
import org.jinterop.dcom.core.JIVariant;
import org.jinterop.dcom.impls.JIObjectFactory;
import org.jinterop.dcom.impls.automation.IJIDispatch;
public class EventLogListener
{
private static final String WMI_DEFAULT_NAMESPACE = "ROOT\\CIMV2";
private static String domainName = "domain";
private static String userName="user";
private static String password="psswd";
private static String hostIP ="127.0.0.1";
private static JISession configAndConnectDCom( String domain, String user, String pass ) throws Exception
{
JISystem.getLogger().setLevel( Level.OFF );
try
{
JISystem.setInBuiltLogHandler( false );
}
catch ( IOException ignored )
{
;
}
// JISystem.setAutoRegisteration( true );
JISession dcomSession = JISession.createSession( domain, user, pass );
dcomSession.useSessionSecurity( true );
return dcomSession;
}
private static IJIDispatch getWmiLocator( String host, JISession dcomSession ) throws Exception
{
//HKEY_CLASSES_ROOT\CLSID\{76A64158-CB41-11D1-8B02-00600806D9B6}
//WbemScripting.SWbemLocator
JIComServer wbemLocatorComObj = new JIComServer( JIProgId.valueOf( "76A64158-CB41-11D1-8B02-00600806D9B6" ), host, dcomSession );
System.out.println("com objected created");
return (IJIDispatch) JIObjectFactory.narrowObject( wbemLocatorComObj.createInstance().queryInterface( IJIDispatch.IID ) );
}
private static IJIDispatch toIDispatch( JIVariant comObjectAsVariant ) throws JIException
{
return (IJIDispatch) JIObjectFactory.narrowObject( comObjectAsVariant.getObjectAsComObject() );
}
public static void main( String[] args )
{
String domain = domainName;//args[ 0 ];
String host = hostIP;//args[ 1 ];
String user = userName;//args[ 2 ];
String pass = password;//args[ 3 ];
JISession dcomSession = null;
try
{
// Connect to DCOM on the remote system, and create an instance of the WbemScripting.SWbemLocator object to talk to WMI.
dcomSession = configAndConnectDCom( domain, user, pass );
IJIDispatch wbemLocator = getWmiLocator( host, dcomSession );
// Invoke the "ConnectServer" method on the SWbemLocator object via it's IDispatch COM pointer. We will connect to
// the default ROOT\CIMV2 namespace. This will result in us having a reference to a "SWbemServices" object.
JIVariant results[] =
wbemLocator.callMethodA( "ConnectServer", new Object[] { new JIString( host ), new JIString( WMI_DEFAULT_NAMESPACE ),
JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), new Integer( 0 ),
JIVariant.OPTIONAL_PARAM() } );
IJIDispatch wbemServices = toIDispatch( results[ 0 ] );
// Now that we have a SWbemServices DCOM object reference, we prepare a WMI Query Language (WQL) request to be informed whenever a
// new instance of the "Win32_NTLogEvent" WMI class is created on the remote host. This is submitted to the remote host via the
// "ExecNotificationQuery" method on SWbemServices. This gives us all events as they come in. Refer to WQL documentation to
// learn how to restrict the query if you want a narrower focus.
final String QUERY_FOR_ALL_LOG_EVENTS = "SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA 'Win32_NTLogEvent'";
final int RETURN_IMMEDIATE = 16;
final int FORWARD_ONLY = 32;
JIVariant[] eventSourceSet =
wbemServices.callMethodA( "ExecNotificationQuery", new Object[] { new JIString( QUERY_FOR_ALL_LOG_EVENTS ), new JIString( "WQL" ),
new JIVariant( new Integer( RETURN_IMMEDIATE + FORWARD_ONLY ) ) } );
IJIDispatch wbemEventSource = (IJIDispatch) JIObjectFactory.narrowObject( ( eventSourceSet[ 0 ] ).getObjectAsComObject() );
// The result of the query is a SWbemEventSource object. This object exposes a method that we can call in a loop to retrieve the
// next Windows Event Log entry whenever it is created. This "NextEvent" operation will block until we are given an event.
// Note that you can specify timeouts, see the Microsoft documentation for more details.
System.out.println("listner statred");
while ( true )
{
System.out.println("vinod");
// this blocks until an event log entry appears.
JIVariant eventAsVariant = (JIVariant) ( wbemEventSource.callMethodA( "NextEvent", new Object[] { JIVariant.OPTIONAL_PARAM() } ) )[ 0 ];
IJIDispatch wbemEvent = toIDispatch( eventAsVariant );
// WMI gives us events as SWbemObject instances (a base class of any WMI object). We know in our case we asked for a specific object
// type, so we will go ahead and invoke methods supported by that Win32_NTLogEvent class via the wbemEvent IDispatch pointer.
// In this case, we simply call the "GetObjectText_" method that returns us the entire object as a CIM formatted string. We could,
// however, ask the object for its property values via wbemEvent.get("PropertyName"). See the j-interop documentation and examples
// for how to query COM properties.
JIVariant objTextAsVariant = (JIVariant) ( wbemEvent.callMethodA( "GetObjectText_", new Object[] { new Integer( 1 ) } ) )[ 0 ];
String asText = objTextAsVariant.getObjectAsString().getString();
System.out.println( asText );
}
}
catch ( Exception e )
{
e.printStackTrace();
}
finally
{
if ( null != dcomSession )
{
try
{
JISession.destroySession( dcomSession );
}
catch ( Exception ex )
{
ex.printStackTrace();
}
}
}
}
}
Error:
org.jinterop.dcom.common.JIException: The system cannot find the file specified. Please check the path provided as parameter. If this exception is being thrown from the WinReg package, please check if the library is registered properly or do so using regsvr32. [0x00000002]
at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenKey(JIWinRegStub.java:195)
at org.jinterop.dcom.core.JIProgId.getIdFromWinReg(JIProgId.java:129)
at org.jinterop.dcom.core.JIProgId.getCorrespondingCLSID(JIProgId.java:160)
at org.jinterop.dcom.core.JIComServer.<init>(JIComServer.java:428)
at com.stg.commons.behave.reporting.EventLogListener.getWmiLocator(EventLogListener.java:49)
at com.stg.commons.behave.reporting.EventLogListener.main(EventLogListener.java:81)
Caused by: org.jinterop.dcom.common.JIRuntimeException: The system cannot find the file specified. Please check the path provided as parameter. If this exception is being thrown from the WinReg package, please check if the library is registered properly or do so using regsvr32. [0x00000002]
at org.jinterop.winreg.IJIWinReg$openKey.read(IJIWinReg.java:938)
at ndr.NdrObject.decode(NdrObject.java:36)
at rpc.ConnectionOrientedEndpoint.call(ConnectionOrientedEndpoint.java:137)
at rpc.Stub.call(Stub.java:113)
at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenKey(JIWinRegStub.java:189)
... 5 more
This is the clue:
"If this exception is being thrown from the WinReg package, please
check if the library is registered properly or do so using regsvr32."
It seems the necessary library of your Windows application is not properly registered yet. From the command prompt (in admin mode), you can use regsvr32 to do that:
regsvr32 yourlib.dll
References:
There is a similar thread here
How to register a DLL using regsvr32 can be found here
I'm about to develop a Java SDK against a REST API and would like to know what would be the best practice approach to building it. I've looked at Google and also used a number of SDKs which connect to REST APIs and there is never much consistency. I've come across some patterns which I find interesting and would like to know which one could be considered best practice, if any, or if there are alternatives?
I've provided sample / pseudo code to facilitate.
1) The models / requests / client are all separated. Example call:
Client client = new Client( ... credentials ... );
try {
Something obj = client.post( new PostSomethingRequest( ..params... ) );
} catch( Exception oops ) { ...handle... }
try {
Something obj2 = client.get( new GetSomethingRequest( id ) );
} catch( Exception oops ) { ...handle... }
2) The models and request are tied together and the client is separate. Example call:
Client client = new Client( ... credentials ... );
try {
Something obj = client.post( new Something( ..params... ) );
} catch( Exception oops ) { ...handle... }
try {
Something obj2 = client.get( new Something( id ) );
} catch( Exception oops ) { ...handle... }
3) The model contains everything. Example call:
Client.setCredentials( ... credentials ... );
Something obj = new Something( ..params... );
try {
obj.post();
} catch( Exception oops ) { ...handle... }
try {
Something obj2 = Something.get( id );
} catch( Exception oops ) { ...handle... }
If there are better ways of building this I'd also be glad to hear about them.
IF you build an SDK for a special REST API, I would use method names that represent the REST service calls and won't be so generic.
Is there any way to access the Windows Event Log from a java class. Has anyone written any APIs for this, and would there be any way to access the data from a remote machine?
The scenario is:
I run a process on a remote machine, from a controlling Java process.
This remote process logs stuff to the Event Log, which I want to be able to see in the controlling process.
Thanks in advance.
http://www.j-interop.org/ is an open-source Java library that implements the DCOM protocol specification without using any native code. (i.e. you can use it to access DCOM objects on a remote Windows host from Java code running on a non-Windows client).
Microsoft exposes a plethora of system information via Windows Management Instrumentation (WMI). WMI is remotely accessible via DCOM, and considerable documentation on the subject exists on Microsoft's site. As it happens, you can access the Windows Event Logs via this remotely accessible interface.
By using j-interop you can create an instance of the WbemScripting.SWbemLocator WMI object remotely, then connect to Windows Management Instrumentation (WMI) services on the remote Windows host. From there you can submit a query that will inform you whenever a new event log entry is written.
Note that this does require that you have DCOM properly enabled and configured on the remote Windows host, and that appropriate exceptions have been set up in any firewalls. Details on this can be searched online, and are also referenced from the j-interop site, above.
The following example connects to a remote host using its NT domain, hostname, a username and a password, and sits in a loop, dumping every event log entry as they are logged by windows. The user must have been granted appropriate remote DCOM access permissions, but does not have to be an administrator.
import java.io.IOException;
import java.util.logging.Level;
import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.common.JISystem;
import org.jinterop.dcom.core.JIComServer;
import org.jinterop.dcom.core.JIProgId;
import org.jinterop.dcom.core.JISession;
import org.jinterop.dcom.core.JIString;
import org.jinterop.dcom.core.JIVariant;
import org.jinterop.dcom.impls.JIObjectFactory;
import org.jinterop.dcom.impls.automation.IJIDispatch;
public class EventLogListener
{
private static final String WMI_DEFAULT_NAMESPACE = "ROOT\\CIMV2";
private static JISession configAndConnectDCom( String domain, String user, String pass ) throws Exception
{
JISystem.getLogger().setLevel( Level.OFF );
try
{
JISystem.setInBuiltLogHandler( false );
}
catch ( IOException ignored )
{
;
}
JISystem.setAutoRegisteration( true );
JISession dcomSession = JISession.createSession( domain, user, pass );
dcomSession.useSessionSecurity( true );
return dcomSession;
}
private static IJIDispatch getWmiLocator( String host, JISession dcomSession ) throws Exception
{
JIComServer wbemLocatorComObj = new JIComServer( JIProgId.valueOf( "WbemScripting.SWbemLocator" ), host, dcomSession );
return (IJIDispatch) JIObjectFactory.narrowObject( wbemLocatorComObj.createInstance().queryInterface( IJIDispatch.IID ) );
}
private static IJIDispatch toIDispatch( JIVariant comObjectAsVariant ) throws JIException
{
return (IJIDispatch) JIObjectFactory.narrowObject( comObjectAsVariant.getObjectAsComObject() );
}
public static void main( String[] args )
{
if ( args.length != 4 )
{
System.out.println( "Usage: " + EventLogListener.class.getSimpleName() + " domain host username password" );
return;
}
String domain = args[ 0 ];
String host = args[ 1 ];
String user = args[ 2 ];
String pass = args[ 3 ];
JISession dcomSession = null;
try
{
// Connect to DCOM on the remote system, and create an instance of the WbemScripting.SWbemLocator object to talk to WMI.
dcomSession = configAndConnectDCom( domain, user, pass );
IJIDispatch wbemLocator = getWmiLocator( host, dcomSession );
// Invoke the "ConnectServer" method on the SWbemLocator object via it's IDispatch COM pointer. We will connect to
// the default ROOT\CIMV2 namespace. This will result in us having a reference to a "SWbemServices" object.
JIVariant results[] =
wbemLocator.callMethodA( "ConnectServer", new Object[] { new JIString( host ), new JIString( WMI_DEFAULT_NAMESPACE ),
JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), new Integer( 0 ),
JIVariant.OPTIONAL_PARAM() } );
IJIDispatch wbemServices = toIDispatch( results[ 0 ] );
// Now that we have a SWbemServices DCOM object reference, we prepare a WMI Query Language (WQL) request to be informed whenever a
// new instance of the "Win32_NTLogEvent" WMI class is created on the remote host. This is submitted to the remote host via the
// "ExecNotificationQuery" method on SWbemServices. This gives us all events as they come in. Refer to WQL documentation to
// learn how to restrict the query if you want a narrower focus.
final String QUERY_FOR_ALL_LOG_EVENTS = "SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA 'Win32_NTLogEvent'";
final int RETURN_IMMEDIATE = 16;
final int FORWARD_ONLY = 32;
JIVariant[] eventSourceSet =
wbemServices.callMethodA( "ExecNotificationQuery", new Object[] { new JIString( QUERY_FOR_ALL_LOG_EVENTS ), new JIString( "WQL" ),
new JIVariant( new Integer( RETURN_IMMEDIATE + FORWARD_ONLY ) ) } );
IJIDispatch wbemEventSource = (IJIDispatch) JIObjectFactory.narrowObject( ( eventSourceSet[ 0 ] ).getObjectAsComObject() );
// The result of the query is a SWbemEventSource object. This object exposes a method that we can call in a loop to retrieve the
// next Windows Event Log entry whenever it is created. This "NextEvent" operation will block until we are given an event.
// Note that you can specify timeouts, see the Microsoft documentation for more details.
while ( true )
{
// this blocks until an event log entry appears.
JIVariant eventAsVariant = (JIVariant) ( wbemEventSource.callMethodA( "NextEvent", new Object[] { JIVariant.OPTIONAL_PARAM() } ) )[ 0 ];
IJIDispatch wbemEvent = toIDispatch( eventAsVariant );
// WMI gives us events as SWbemObject instances (a base class of any WMI object). We know in our case we asked for a specific object
// type, so we will go ahead and invoke methods supported by that Win32_NTLogEvent class via the wbemEvent IDispatch pointer.
// In this case, we simply call the "GetObjectText_" method that returns us the entire object as a CIM formatted string. We could,
// however, ask the object for its property values via wbemEvent.get("PropertyName"). See the j-interop documentation and examples
// for how to query COM properties.
JIVariant objTextAsVariant = (JIVariant) ( wbemEvent.callMethodA( "GetObjectText_", new Object[] { new Integer( 1 ) } ) )[ 0 ];
String asText = objTextAsVariant.getObjectAsString().getString();
System.out.println( asText );
}
}
catch ( Exception e )
{
e.printStackTrace();
}
finally
{
if ( null != dcomSession )
{
try
{
JISession.destroySession( dcomSession );
}
catch ( Exception ex )
{
ex.printStackTrace();
}
}
}
}
}
~
On the Java side, you'll need a library that allows you to make native calls. Sun offers JNI, but it sounds like sort of a pain. Also consider:
https://github.com/twall/jna/
http://johannburkard.de/software/nativecall/
http://www.jinvoke.com/
On the Windows side, the function you're after is OpenEventLog. This should allow you to access a remote event log. See also Querying for Event Information.
If that doesn't sound right, I also found this for parsing the log files directly (not an approach I'd recommend but interesting nonetheless):
http://msdn.microsoft.com/en-us/library/bb309026.aspx
http://objectmix.com/java/75154-regarding-windows-event-log-file-parser-java.html
Read this article.
JNA 3.2.8 has both methods to read and write from the Windows event log.
You can see an example of write in log4jna.
Here's an example of read:
EventLogIterator iter = new EventLogIterator("Application");
while(iter.hasNext()) {
EventLogRecord record = iter.next();
System.out.println(record.getRecordNumber()
+ ": Event ID: " + record.getEventId()
+ ", Event Type: " + record.getType()
+ ", Event Source: " + record.getSource());
}
If you want true event log access from a remote machine, you will have to find a library which implements the EventLog Remoting Protocol Specification. Unfortunately, I have not yet found any such library in Java. However, much of the foundation for implementing this protocol has already been laid by the JCIFS and JARAPAC projects. The protocol itself (if I'm not mistaken) runs on top of the DCE/RPC protocol (implemented by JARAPAC) which itself runs on top of the SMB protocol (implemented by JCIFS).
I have already been using JCIFS and JARAPAC to implement some of EventLog's cousin protocols, such as remote registry access. I may be blind, but documentation seemed a little scarce regarding JARAPAC. If you are interested in implementing this, I can share with you what I have learned when I get some spare time!
Later!
there are a million (and one) options here ;)
you could look at sigar
http://cpansearch.perl.org/src/DOUGM/hyperic-sigar-1.6.3-src/docs/javadoc/org/hyperic/sigar/win32/EventLog.html
mind the licensing though....
or you could be quick and dirty and just periodically execute (and capture the output)
D:>cscript.exe c:\WINDOWS\system32\eventquery.vbs /v
then use event filtering params to refine the results etc...
http://technet.microsoft.com/en-us/library/cc772995(WS.10).aspx