Search code examples
javajakarta-eejarwarear

Java EE - Get Cell/Node information from class


I have a need to interface with C/C++ from Java Enterprise applications. I would like to write a class that will be able to gather Node/Cell information, possibly any additional information about where the app is deployed, so I can, from C++, trace back to the JAR in the filesystem where the call came from (authoritatively). Is there a particular Java library that I could utilize that will give this kind of information about the application? Ideally, what would happen is: (lets call it EnvProvider)

  1. Java App calls EnvProvider
  2. EnvProvider gathers information about the Java application that invoked it
  3. EnvProvider calls wrapped C++ (CORBA, SOAP perhaps?) and passes this information
  4. C++ traces back up the filsystem to the calling app, to inspect the actual JAR files where purported application call came from.

It sounds trivial (outlined here in a mere 4 steps) but from my research thus far, it appears that there is no good way to get enough information about the Java Application FROM the Java Application itself. By "enough" information, I am talking about enough to give the C++ enough information to walk a filesystem and find a deployed EAR, JAR, WAR.

Any information that you could provide would be GREATLY appreciated!

Regards

Chad

* EDIT *

Kim, thank you for the response. Let me explain a bit why I need to get this particular trace.

I am working on/with a cryptographic library that is written in C/C++. They were written by my predecessor here (where I work) and they are very well tested. They provide more than just encryption, however, and the algorithms that are contained within are proprietary and need to remain secure. This rules out implementing the same in Java, as Java is too easily reverse-compiled. In fact, my predecessor went to great lengths (justifiably) to obfuscate the C/C++ source. These libraries work well with Shell, native C/C++ binary executables (.exe, etc.) as well as other applications where the call will come from a (mostly) wholly contained application. This source provides ways to ensure that the application calling it is in fact a trusted application (sounds similar to code signing, but I can assure you that what it does with these source files is far more complex).

I am trying to extend this functionality into our Enterprise Java architecture and in order to do so, I need to be able to get back to where the call came from, even if that means just getting to a deployed WAR or even the EAR that the app was packaged in, so I can use the source files with the C/C++ source. So if the call came from application A, and application was deployed in App_A.EAR, I would like to get that info and call out to the C/C++, trace back to that EAR and work with it. If that sounds confusing, I apologize, but I am (as a matter of conduct) leaving out a large part of what the files (.exe or JAR/WAR/EAR) are used for.

Thank you again for any assistance you could provide!

* EDIT *

Chad


Solution

  • I have three concerns you might want to consider before I get to the answer:

    1. Why do you need to find the underlying jar/ear/war/class file? Are you worried about running malicious code? If so, then I strongly recommend using code signing and security policies instead. Those are the proper tools that come built-in with the platform.
    2. Application servers as well as enterprise applications might use custom class loaders that could store the jar or class files in a way that isn't immediately accessible to other applications. I can't remember any examples of such, but this bear in mind that Java does not impose or mandate any one way for how class loaders maps resources to physical files, as long as they do it consistently. By design, the interface for loading classes and resources is deliberately decoupled from the idiosyncrasies of the underlying operating system. Especially enterprise application implementations could have an incentive to mess with the way jar files are stored if it helps speed up and manage class loader managed resources.
    3. For clustered environments, you're probably out of luck. All the pieces that facilitate communication between the different nodes in a cluster are not prescribed nor governed by the Java Enterprise Edition specification. A particular vendor might have proprietary interfaces that allow you to determine which node a remote interface is talking to, but since the goal of clustering and load balancing is to make it transparent to the app and its clients, you're probably even less likely to get access to this information.

    Okay, on to the answer. You might want to try looking into Class.getProtectionDomain and ProtectionDomain.getCodeSource:

    ProtectionDomain protectionDomain = someObject.getClass().getProtectionDomain();
    SourceLocation sourceLocation = protectionDomain.getCodeSource();
    URL url = sourceLocation.getLocation();
    

    Beware that calling getProtectionDomain might cause a SecurityException depending on the security policy in effect.

    Update:

    It sounds like your software is struggling with security and trust issues. But you don't have to inspect the binary code each and every time you run the code. You can achieve the same level of trust with code signing. How? You sign the code.

    1. When an external application needs to interact with your library, ask for a copy of the binary code for inspection.
    2. When you're satisfied with the result, sign the code using your own private key.
    3. Next, set up a security policy that will only allow applications signed by you to run.

    With e.g. RSA and a 2048 bit key, or even larger key sizes, it is practically impossible to substitute any part of the signed code with today's known attacks against RSA.

    This strategy require that you control the application server and the JVM on which it is running. If your trust issues go beyond this, you probably need to start thinking about mandating an open source application server, where you can inspect the source code and sign the binaries, and, ultimately, the JVM itself.

    Without knowing specific details about your architecture and setup, I will still recommend leveraging the security features built into the Java platform.