the problem is quite simple yet maybe not resolvable?
Atleast for me :/
Situation:
Let's say I have a dynamic Page System where the Server provides additional copies of self containing GWT Modules. Meaning a main GWT instance on the client side is supposed to manage the new incoming GWT Scripts, which are simply added by the main instance itself using Tags.
Now the main GWT instance needs to communicate with the newly created script instances in the most easiest (GWT internally) way possible.
So what is out of the question: Writing stupid JSNI Wrappers on both sides, if not absolutely required.
Soltuions I came up with were:
Make a module both use, including a common interface, example:
package com.whatever.interfaces;
public interface Communication {
void showMessage(String message);
}
So both would now inherit this module and know of the definition.
The main client would now load the dynamic JS and register an implementation of Communication and the dynamic one would go and use it. I tried storing references on $wnd and on elements using setPropertyObject. On $wnd they are null, which maybe/probably related to the the GWT Iframing? For the property on the RootPanel element for example, ClassCastException would be raised.
Is there any good way to encounter this? Another idea I have is using JSNI for calling the interface as an implementation on the bridge module, but I'm not sure if this a good way.
Your help is appreciated, thanks.
EDIT:
Well I have pretty much come to the conclusion that this is not possible whatsoever.
Even though you might have used same interfaces somewhere, they will be very own instantiations of it, for different modules compiled, even if using the same module as a common ground.
The approach using JSNI certainly is somewhat possible, but not without mapping all attributes to real JS Objects and remapping them back. Meaning you can't pass complex Java Objects around like you probably would be used to. My conclusion would be, using CodeGenerators you could build the JSNI Wrappers automatically and the remappers, for both modules, but this is too much of a hassle for me.
I'm still open if someone comes up with a better idea, but I just want to provide some inside on my findings, so others can benefit of my wasted time ;)
A while ago, I created a simple prototype implementation to share Object instances to other GWT modules. You can find the code on https://code.google.com/p/gwt-plug/. And yes, as you described, it's a problem to transfer Java objects. As far as I remember, you can only transfer primitive values (int, float, ...), Strings and JavaScriptObjects. But JavaScriptObjects are a good possibility
As you already found out communicating between separately compiled GWT modules is somewhat of a challenge since everything is obfuscated. It is possible though through javascript, JSNI, JSO's and JSON.
You can use JSNI to create communication hooks through javascript directly on the $wnd object. Sort of an event bus approach would work.
You can use JSON to pass around complex objects.
You can use JSO's (JavaScript Overlays) to consume and manipulate the JSON in each of the disperate modules.
Putting all that together you would end up with a mini-framework library module that you would share between the various GWT modules you want to have communicate with each other. They would each inherit the common framework module and compile in their own obfuscated form but since they are using javascript and JSON as a common language they won't have to worry about the obfuscation.
Make sense?
As explained in the xsee's answer, you can create a hook from GWT using JSNI
In order to do this, take a look to very useful project http://code.google.com/p/gwt-exporter/
Related
I have created two micro-services using java. I need to make a REST api call from service A to service B. The data sent will be in JSON format. Using jax-rs I need to create entity class in both the service.
Since both the entity class be same in both the projects. Do i
Create an common jar and use is for all my entity/domain objects? Does this make my microservice more tightly coupled?
Do i create the same class in both the microservice projects? This will just mean repeating the work in both the projects?
Is there a better way to communicate between the sevices?
In terms of having your two micro services independent and having them also independent in the future I would also duplicate the code. We had the exact same situation before. Several microservices seem to use some "common" classes that can be put to a seperate jar.
In the end we had following situation:
several (5+) services using the same JAR
turned out that classes that we thought are the same, seemed to have slightly different semantics in different services
a change on one of the classes more or less forced us to have a release on every microservice, when it came to releasing (no independency here anymore)
developers tend to see "common" behavior everywhere, so you most likely end up with some "Helper/Utility" classes there as well which is in the meanwhile considered a code smell in OOP
Long story short, in the meanwhile we switched to having the code duplicated, which gives us the freedom to handle our mircoservices really independently, as we only need to stick to the service contract. What happens internally is fully up to the service and we don't have to release all services in the end of an iteration. I'm not saying that the other option is wrong, but it turned out that it was not suitable for us. If you really see common classes between two services and you are sure you don't mess your common library up with other crap, your save to go.
EDIT
Maybe as follow up, we had the same discussion in regards of tests (unit and integration) having share test code in some common classes. In the end this was hell, as every slight change in code or acceptance criteria made 50% of tests fail. Meanwhile our strategy is to not share anything on test level and have everything right at the tests place. By that you are super fast in eliminating or changing tests. In the end the lesson for us was to keep business code as clean and elegante as suitable and the test code in a way to give us the least headache possible.
Edit2
Meanwhile, we define all our REST interface with open api specifications and create the actual DTO objects that are exchanged via the maven plugin openapi-generator. The spec resides in the project that implements the interface and it is published to artifactory. The project implementing the client pulls it and creates DTOs based on that. By that, you have a single point of truth and no need to write DTO boilerplate code.
I'd say it depends on the situation. If you use a shared package, this will introduce a coupling between the two projects. This makes sense, if both of the project build up on the same data classes and therefore will have the same dto objects to work with. Ideally you would have your own nexus which simplifies the usage of the shared artefact.
Otherwise, if only a few classes are redundant I probably would implement it in each sevice separately, which decouples them too.
I am afraid that you need to decide which one the right solution is for your project.
This is common situation where we as developer gets confused. I would suggest to have a common jar(shared) which can be used in both micro services (A and B). It is nothing but sharing a third resource as we use third-party libraries.
In my current project we were in the same situation and we found the best approach to have separate shared libraries(api-shared as name) and consuming it as jar in different micro-services.
In your second approach you ended up with redundant code and also difficult to maintain. Lets say if you have any changes in entity then you have to change in both the entities which is not quite a good way to synchronize the thing.
All in all I would suggest you to use shared jar for both micro services.
Regards
Techno
I am working on an API for a software so my users can extend it without modifying the source code. But, I want only certain functions to be accessed by certain classes for security reasons. Is there anyway to do this? Also, I have no code because I have no idea on how to do this.
Thanks! -Trent
I have two thoughts on this, one is that you can look at how Minecraft Forge created their plugin API.
Another way is to have a limited API between your core code and the actual plugins, but, you need to be careful of the platform. For example, if you write the core application in Java or C#, then I can use Aspect Oriented Programming (AOP) to bypass your security and have my code change the behavior of yours.
If you use functional programming (FP) languages, then you can protect more from this type of approach, if you also are not using languages on these platforms, but they are not perfect.
So, there is a trade-off between power and convenience, so how useful do you want your application to be, and how secure?
One possible solution that may work is if you go with something similar to Minecraft, though I doubt they do this, but, give a stub application to the user. They can extend it with plugins, and the interface functions they can modify are in the stub. When the program starts, the plugins are loaded, and the interface may be modified or extended, but, then the core program is pulled down and put into the stub, and then the actual program runs. The core program can be recompiled and manipulated so method names are changed, so reflection is harder to use, but taking this approach, and doing it well, would be hard.
BTW, I like Alex T's response, I just gave different terms to some of his, such as AOP instead of reflection and immutability is part of FP.
You mention jar, which means you are using something that runs on a JVM, so you may want to read up on AspectJ, as it can significantly alter the behavior of applications. You can have private methods, but I can put code that runs instead of yours, or change the parameters or the return value before or after the method is called.
To protect variables inside of classes, you can make them private, and accessible via getter and setter methods with varying levels of protection. This also applies to classes themselves; if you wanted to prevent the user from being able to instantiate a class, you could mark the class' constructor as protected to allow instantiation only within it's package.
If you wanted to hide the implementation details of a class altogether, you could declare the class as class X instead of public class X, which would hide methods from the API for standard development.
This will quickly get you the behaviour you're after, but there's an aspect of Java called reflection, which allows an executable Java program to analyze and manipulate it's own implementation; in this regard, no field or method is ever completely safe.
You can also safeguard variables by providing access to them via 'immutable' Objects; these are objects designed to forbid the caller from modifying the original source contents.
I have a gwt project that acts as a semantic engine for other projects.
I recently realized very very little of the code is specific to gwt. Its almost all pretty basic java. In fact, the only things specific to gwt is retrieving files.
So what I would like to do is to separate out the gwt completely so I can use the same basic code for other Java projects - such as Android or Processing apps.
So, "Semantic Core" project could be inherited by GWT,Android and Processing apps and I wont have to maintain separate versions for each.
To do this, however, I need some way for other projects to "give" the Semantic Core project their own file-handleing methods.
My current idea how to do this;
One method I thought how to do this was to have SemanticCore define a Interface for FileManager with a method like;
getFile(String,MyErrorHandler,MySuccessHandler)
And then have the class's for MyErrorHandler and MySuccessHandler defined also in the SemanticCore project, effectively being runnables that take a string as a parameter.
With this Interface defined, other projects (GWT,Android etc) have to define their own class that implements it
eg, GWTFileHandler implements FileManager
Then create a object of this class, and pass it to the SemanticCore;
SemanticCore.setFileManager(new GWTFileHandler());
The semantic core can then use it at its leisure to retrieve files in a way suitable for the platform its on.
Question;
Is this a good way to do it? It seems wrong to me I am creating a new object, when I'll only be using static methods from that class.
Alternatives?
I hope my description is clear. As this all has to be GWT compatible in the "SemanticCore" project, any use of reflections is ruled out.
Thanks,
The recommended approach IMO is to use Deferred Binding to pick the GWT compatible version of your FileHandler or other GWT specific implementations. Extract the common interface for all versions and in your GWT module file you point to correct GWT implementation.
You can then instantiate your specific implemenation using GWT.create :
MyInterface implemenation = GWT.create(MyInterface.class);
more in depth info on the gwtproject site.
Deferred Binding is a technique used by the GWT compiler to create and
select a specific implementation of a class based on a set of
parameters. In essence, deferred binding is the GWT answer to Java
reflection. It allows the GWT developer to produce several variations
of their applications custom to each browser environment and have only
one of them actually downloaded and executed in the browser.
Since the whole Android stuff is open source I was thinking about to do some minor modifications in a few internal classes from the com.android.internal.telephony package and of course then I would love if somehow my application could use the modified classes. I was thinking about replacing the classes with the original ones at runtime by using reflection or other kind of unknown java tricks :D ...maybe what I'm trying to do is impossible :( I don't know that's why I'm asking.
Note: The changes in the internal classes would not change their functionality in any way, its more about extending their functionality so even if other apps would use the modified versions it would not break them!
Why I want to do it? What I'm trying to achieve ?
Well i would like to modify the com.android.internal.telephony.gsm.CallTracker internal class so i could do proper call handling (call blocking etc..)
Maybe if you know about another way how to do what I want to I would like to hear about it :)
Note2: I know about the method when you handle the android.intent.action.PHONE_STATE, action , but its simply too late to react when this action is broadcasted. I'm really looking for a better solution even if that solution involve ugly hacks :)
As always thanks for all your replies...
You cannot do this :) I'll let you imagine what would happen if any application was allowed to freely replace core parts of the system. You can download the Android source code and you can modify it and you can upload the modifications to your phone (if your phone is rooted/unlocked) but you cannot apply such modifications with a simple app.
Changing a classes functionality (methods, byte code) after a class ha been loaded is impossible. Reflection/Invocation does not affect classes but static fields and instances only.
Your looking at a way to add additional methods or change existing methods of a running system, because the classes in question probably will be loaded already when your 'hacking' application is executed.
The only technical approach that I see is to change the classes in advance and deploy a modified system. I'm just ignoring possible licensing issues and security at the moment. But even with this way, your software would depend on a custom OS, a branch from some andorid version, disconnected from official updates, and you'd have to ask your customers to install a custom OS with, say, unknown features.
Sidenote - I'm very happy, that this is really impossible, otherwise my mobile would already be full of trojans, viruses, etc...
Romain is correct you can't and shouldn't try to change existing system classes.
That said, implementing call screening as you suggest should be possible by creating a replacement to the dialer application that handles phone calls.
Specifically the intent ACTION_ANSWER should be handled by your application, which could then either implement a dialer-like interface or open the dialer app (or any other call manager) explicitly.
There are actually ways to hack on Android framework classes, it just depends on which ones you want to hack.
You must extend the class you intent to hack on.
If you want to override package private methods and/or access package private variables you can put your class in the same package.
You can use reflection.
I've actually had to do this to work around bugs. Romain is correct, to an extent. It all depends on the structure of the code you are trying to hack on. You definitely can't hack on Android internals, but you can hack on other framework classes like Activity, View, etc.
I wonder if I should use it, in this example. I'm reading files, and I need to store one parameter with that file.
According to this parameter I'm bundling files together and sending them over the wire.
I came accross jaf activation framework, and I'm not sure if it is appropriate to use it in such simple example.(store 'file' into DataHandler with this parameter or to make me simple holder). Of course I don't know if requirments can change in the future, and I will need more.
What do you think about it?
My impression is that it's too much, it's difficult to get proper sources. But on the other hand it has what I need.
The question could be more general as well, should I use framework which can do a lot more, if I need something really simple and I can code it quickly?
thanks in advance
To answer your more general question, I would most often make use of frameworks wherever possible.
It's always possible that you're going to want more functionality in that area. If you're using the framework then great. Otherwise you have to back out and rewrite. Or maintain two different implementations.
Frameworks have been debugged/tested etc. and will handle the edge cases. Often what you think of as being trivial ends up more complicated than you first thought.
Don't forget that due to how class loading works, the JVM will only load the classes you require. Consequently you're only affecting the size of deployment of your application, not the runtime size (by referencing a sizable jar)