I am writing a piece of software that needs licensing from government authority, there are more modules of the same kind (but doing different work - math algorithms). I need to secure that anytime anyone (mostly a representative of government authority) comes to this software and asks for it (via network), the checksum for that particular module is printed out. I am writing this server in Java. I looked into Serialization but it only cares about the data (attributes) in the object and not the object behaviour or other logical structure - which this absolutely needs to care about. Hence I need to access the .class from within the running jar file and perform a checksum on it. The current structure is like this:
abstract class Module {
public abstract void run();
public String chsum ();
}
abstract class SimpleGame extends Module {
/* not that important */
}
class GameX extends SimpleGame {
public void run() {
/* some magic */
}
}
And when needed, upon receiving the proper message the network stack might call something like:
GameX gx = new GameX();
String checkSum = gx.chsum();
My current progress got me nowhere, I tried to access the .class file but without any luck - it works only if it is not a jar archive. And I need to supply the Class instance which is not a dealbreaker but it sure is not that handy. If I could get an array of bytes containing the compiled .class file that would be more than enough - to perform a checksum on that is a piece of cake using MessageDigest
Related
I'm looking on guidance on how I can essentially create an 'empty shell' jar with maven. The idea is I have a java project, and I want to export the my.project.api classes (with package) into its own jar without saving the methods / constructors actual code inside.
For example, lets say I have the following:
public class Test {
public void doSomething(String message) {
System.out.println(message);
}
}
I want to export a separate jar which would keep its package declaration, and export as:
public class Test {
public void doSomething(String message) {}
}
The reasoning for this is the project itself is exclusive, but I want to allow other developers to make their own integrations without the need of the physical product / project. This way by them hooking into say my.project.api.Test, they'd be able to see the methods and do as they wish.
Hopefully this clarifies enough, it would export as a separate jar maybe as 'MyProject-API.jar' or something.
Thanks!
This very much looks like a use case for interfaces.
I have a third party application which includes a suite of DLL libraries that provide access to the application's data and commands.
Using Java, I want to access these DLLs in order to retrieve some specific data and write it to a file.
While similar questions to this have been asked before, I haven't found any that have helped me (I'm an absolute beginner at Java). I suspect this can be done with
JNA but need some guidance. It might be beyond my novice ability but I want to try.
There are several DLL files I need to access, each of which contain multiple libraries, which provide access to objects offering various functionality.
I need to gain access to these DLLs, instantiate objects from them, and gain access to the methods and variables provided. Is there a relatively easy Java solution that anyone knows of?
Thanks
EDIT: I've added example J++ code illustrating what I need to do in Java. J++ would firstly require creating COM wrappers for each of the required DLL files.
import dll1.*;
import dll2.*;
import dll3.*;
import com.ms.com.*;
public class Class1 {
public static void main(String[] args) {
// Create an application object
dll3.Application app = new dll3.Application();
// Use the getDataManager() method on the application
// object to get the DataManager object (which in turn is
// used to create the price object)
DataManager dm;
try {
dm = app.getDataManager();
} catch (Exception e) {
System.out.println(e);
return;
}
// Create the price data object using the CreateOb method of the
// DataManager object
PriceOb dp = (PriceOb) dm.CreateOb("Price");
// Set the requests parameters and make the request
dp.setVar1("abc");
dp.setVar2("xyz");
dp.Request();
I am trying to write an annotation processor in Java 6. I wrote a sample implementation, which creates a new source file in the process method and it works fine.
#SupportedAnnotationTypes(value = {"*"})
#SupportedSourceVersion(SourceVersion.RELEASE_6)
public class BrownfieldAnnotationProcessor extends AbstractProcessor{
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
try {
JavaFileObject f = processingEnv.getFiler().
createSourceFile("in.test.ExtraClass");
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
"Creating " + f.toUri());
Writer w = f.openWriter();
try {
PrintWriter pw = new PrintWriter(w);
pw.println("package in.test;");
pw.println("public class ExtraClass implements TestInterface{");
pw.println(" public void print() {");
pw.println(" System.out.println(\"Hello boss!\");");
pw.println(" }");
pw.println("}");
pw.flush();
} finally {
w.close();
}
} catch (IOException x) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
x.toString());
}
return true;
}
}
But in my case, i do not want another java file to be created and instead i want to generate a class file directly. How to create a class file? Should i use a dynamic compiler to compile this source in string to create the class? In that scenario, i can directly store the class files in the file system. What is the usage of
processingEnv.getFiler().createClassFile()
method?
I tried googling around, but could never find an example using this method.
I see only few reasons for creating class files instead of source code files. Actually this are the same reasons why you would ever need to create bytecode by hand in any situation.
You absolutly need control over the bytecode (maybe for 'optimization' or testing purposes)
You need to use features that are available in bytcode but not in the Java language
I think you rarely need to do any of the above. If this is really what you want to do, you should know a lot about the format of class files and bytecode of course. You would basically be creating some kind of compiler at this point.
You could argue that by shipping precompiled classes, or by generating bytcode directly, you can skip a step in the built process and the user's program will compiler faster. That may be true true but I'm sure the speed will be neglectable. It would be easier to just work with source code and pass it to the filer for compilation.
Should i use a dynamic compiler to compile this source in string to create the class?
No, I see no advantage here. If you create a source code file with the filer it will be compiled automatically. You only need to do this if your source code is not Java but some other language that you want to compile for the JVM.
I have written this project and already use it in other libraries of mine.
However, I find something amiss. Namely, in each user of this library, I create a utility class whose only role is to provide one or more MessageBundles. And this sucks.
I'd like to have, built into the library, a mechanism in order to have library users be able to register/recall bundles.
My first idea would be to have a singleton factory with a .register() and .get() method (with appropriate checks for duplicate keys etc) and call these from within static initialization blocks...
... But there is a problem: there is no guarantee as to which static initialization block will be called first.
Knowing that I'd like to keep the dependencies of this library "intact" (which is to mean, no external dependency at all), what solution would you recommend?
(note: this is Java 6+)
You could use the standard support for service providers: ServiceLoader. You would simply require each user of your library to provide an implementation of some interface, for example
public interface MessageBundleProvider {
List<MessageBundle> getBundles();
}
The name of the class implementing this interface would have to be specified in a file of the jar file of the user library named META-INF/services/com.example.MessageBundleProvider.
At runtime, your library would automatically discover all the message bundle providers using the following code:
private static final ServiceLoader<MessageBundleProvider> LOADER
= ServiceLoader.load(MessageBundleProvider.class);
private static final List<MessageBundle> BUNDLES;
static {
BUNDLES = new ArrayList<MessageBundle>();
for (MessageBundleProvider provider : loader) {
for (MessageBundle bundle : provider.getBundles()) {
BUNDLES.add(bundle);
}
}
}
Disclaimer: I know that ServiceLoader exists, but I've never used it before. It's how all the standard Java service providers are discovered, though (like JDBC drivers, charset providers, etc.).
Okay, this had been making me very mad. I've followed almost 8 tutorials all over the Internet and in the end, I got my Red5 server instance working. Good for me! But when I'm calling my Java methods in my Red5 apps from my AS3 apps, in the 'Console' window in Eclipse, I got this error :
[ERROR] [NioProcessor-1] org.red5.server.service.ServiceInvoker - Method getTheName with parameters [] not found in org.red5.core.Application#17e5fde
Here's my Application.java file.
package org.red5.core;
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.IScope;
import org.red5.server.api.service.ServiceUtils;
/**
* Sample application that uses the client manager.
*
* #author The Red5 Project (red5#osflash.org)
*/
public class Application extends ApplicationAdapter {
/** {#inheritDoc} */
#Override
public boolean connect(IConnection conn, IScope scope, Object[] params) {
return true;
}
/** {#inheritDoc} */
#Override
public void disconnect(IConnection conn, IScope scope) {
super.disconnect(conn, scope);
}
public String getTheName() { return "MyName!"; }
}
And here's my AS3 code. I just put this on the Timeline.
var nc:NetConnection = new NetConnection();
nc.connect("http://localhost/Mintium/RoomHere", "SomeUsernameHere");
nc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
nc.objectEncoding = ObjectEncoding.AMF0;
function onNetStatus(e:NetStatusEvent):void
{
switch (e.info.code)
{
case "NetConnection.Connect.Success" :
trace("connected");
nc.call("getTheName", new Responder(getName_result, getName_error));
break;
}
}
function getName_result(res:Object):void { append("Name : " + res.toString()); }
function getName_error(res:Object):void { append(res.toString()); }
Its been a week I've been trying to figure it out and my dateline is next month. If this stuff is not solved, I'm gonna fail my assessment. Please help me with my problems. Thank you very much.
Sorry I did not see this 2 months ago, I could have helped you pass your assessment. Nevertheless, I think I can answer this question, having had a similar problem calling Red5 services.
The key to solving this problem is in those parts of Red5 that utilize the Spring Framework. In your project, there should be a file called red5-web.xml that resides in the Server project's WEB-INF folder. This file contains some Bean dependencies used by Red5's Spring components. This is not mentioned in the tutorials that I read, or even in most of the (rather sparse and distributed) red5 programming documentation.
What you have to do is add a bean entry for your method in that file. In your case, the entry should look like this:
<bean id="getTheName.service" class="org.red5.core.Application" />
Note my use of the name of your function, with ".service" appended. I do not understand why, but you need the ".service" appended in order for Red5 to find your function. You need to add a similar entry for every class whose functions you want to use as services.
Of course, I based everything I said above on the fact that you put the service into the Application class -- something which I never do. if you read the red5-web.xml file, you will see that there is already an entry for that class, because it is already injected through Spring as the class that acts as an "endpoint" for processing requests over the web. I do not know if using the Application class as an endpoint and a provider of services is a good idea (it violates "separation of concerns" in OOP and may cause problems with Spring).
What I usually do is add a separate class in the org.red5.core package (or any other package you might want) that acts to deliver the desired service, then put an entry into red5-web.xml that injects the class and its method. So, for your project, lets assume you have a class called NameProvider in the org.red5.core package:
public class NameProvider
{
public NameProvider() {}
public String getTheName() { return("MyName!"); }
}
then you add the following entry to your red5-web.xml file:
<bean id="getTheName.service" class="org.red5.core.NameProvider" />
That should make everything work.
I hope this helps you in the future, or anyone else having this problem. I just wish I'd seen this question sooner.