This is what i intend to do:
I want to write a Aspect oriented NLog specific onmethodexecutionaspect class.
But i still want to ensure that the calling code is attributed using a general attribute class which will internally load the NLog or TraceX etc specific implementation of methodexecutionaspect depending on what is specified in the application configuration file.
What is the best way to approach this?
I am thinking of writing a abstract class which will derive from postsharp method execution aspect.
Then i will have another dll which will have a NLog specific implementation... so it will have a class which will derive from the general method execution aspect class i have created in the general dll.
The consuming code will only reference the general class dll i have written, and that class will doa load of NLog specific dll i have written if that is what is specified in the application config.
makes sense?
I think you are on the right track.
However, try using OnMethodBoundaryAspect instead. It is faster at runtime than OnMethodInvocationAspect.
Try to take advantage of compile-time initialization (CompileTimeInitialize) and run-time initialization (RunTimeInitialize) and avoid doing anything costly in handlers.
Related
All, Here is a problem that my searches have yielded little insight into. I think this should be a fairly common problem for all of us developing against big data frameworks but also seek 100% test coverage. So I will post the question here in an attempt to gather the best community response & ideas.
Consider the scenario where we need to mock a class that instantiate an external API object
class SolrClientWrapper {
def doWork() = {
val cli = new CloudSolrClient("zkHost1")
???
}
}
To get 100% test coverage, and without actually relying on the Solr server to be up at all times during unit testing, we shall have a way to intercept the call to new CloudSolrClient. As far as I know, the ONLY library available is PowerMock
Here is The Twist
PowerMock and other Mock libraries require asm as a dependency, but a complex framework Spark project also require asm. There are version conflicts and thus (test-)runtime hell.
What is the best design refactor/libraries for this situation?
Instead of creating a new CloudSolrClient object within the SolrClientWrapper class, it should be passed as a dependency. Then in your test you can pass a mock instead of the real object. Note that there are many dependency injection frameworks and mechanisms that can make it easier for you to manage your dependencies (e.g. to automatically instantiate them and pass to the constructor for you).
Not sure what asm is, but the code you posted should be easily testable without such dependencies once you remove parts of the code that instantiate stuff inside the class body (and thus the need to "intercept" anything).
I have read that for GWT, specifying methods to return a concrete implementation, for example:
public ArrayList<String> getList();
instead of the normally-preferred "abstract interface", for example:
public List<String> getList();
results in GWT producing a smaller compiled javascript file, because the client (ie js) code doesn't have to cater for all known implementations of the interface (in the example of List, the client code would have to be able to handle LinkedList, ArrayList, Vector, etc), so it can optimize the js by not compiling unused implementations.
My closely-related questions are:
Is this true? (the following questions assume it is true)
Is the optimization per-class that uses interfaces, or per application? ie
Do I see a benefit just refactoring up one class? or
Do I only see a benefit once all client classes are refactored to not use interfaces?
The following assumes that you use the interface as part of the signature of GWT RPC service. I think if you do not use the interface in the signature of GWT RPC service, the effect of using classes instead of interfaces should be minimal (e.g. the GWT compiler will only compile the used implementations)
Is this true? (the following questions assume it is true)
Yes, the output of the GWT compiler gets smaller when it 'knows' better which classes might be send from server to client.
Is the optimization per-class that uses interfaces, or per application? ie
In case of GWT RPC, per application.
Do I see a benefit just refactoring up one class?
Yes, one interface replaced by an implementation can reduce generated code size by a few kb, if the interface would require to include code for many classes.
However, apart from using implementations instead of interfaces, also a 'blacklist' of classes can be defined in the module definition file to explicitly circumvent the inclusion of implementations in the generated code: something like
<extend-configuration-property name="rpc.blacklist"
value="-java.util.ArrayList" />
I just did a test based on the sample app generated by webAppCreator, but I added 3 simple services that returned either List<String> or ArrayList<String>, depending on the build.
The results were that having all services use ArrayList<String> saved about 5Kb from the compiled javascript over having any mix of the return types.
That proves the saving is real and per-app (not per-service).
It also show how much it saves (in this case).
This doesn't actual to the GWT-compiler in general. Such approach is applied only for classes used with code generation. For example, when using Remote Procedure Calls. See this question for more detail information. Thus, if you declare an interface instead of a concrete class as the return type, the compiler includes all possible implementations in your compiled code. This increases time of compilation and a amount of generated code.
Actually one might develop application using GWT without RPC. In this case compiled code doesn't bloat when using interfaces.
In drools, we often have common logic that needs to be invoked. There are two options to achieve this.
Use function in drools.
Move the common logic to some Util class in java and invoke it from drools.
Which of the above is recommended?
Thanks.
I always recommend using imported static methods unless it is a very simple piece of logic that is local to a subset of your rules and needs to be dynamically defined. The reasons are:
keep DRL code clean of procedural logic, making maintenance cheaper and easier.
it is easier to write an xUnit test to test your function logic in a static method than it is to test a DRL function.
it makes the function available to all DRL files, without conflicts and without IDE error codes.
The DRL function construct is a facility to solve simple local problems, but java classes are where you want to keep and maintain your procedural code.
Lets say I have a class...
com.mycom.app.AbstractMessage
There is another class in
com.mycom.model.QueryResponse
QueryResponse extends AbstractMessage and notice they are in different pacakges
com.mycom.model is a GWT Module and in the module XML
When I compile model there are errors. However when I try to use QueryReponse in another GWT module, I get runtime errors
"No source code is available for type com.mycom.app.AbstractMessage; did you forget to inherit a required module"
This lends me to believe that AbstractMessage was not compiled/compiled right to begin understandably because I DO NOT WANT to have "app" package be a GWT module
In other words, I only want to compile all classes in "model" and not any super classes. How can I tell the GWT compiler/rpc/linker/serializer etc not to do so?
i.e Is there a way to tell GWT not to walk beyond certain classes when it serializing/compiling it
I am doing this a source environment where we have a lot of packages, most of them depend on MODEL only and I DO NOT want to make a GWT module out of every package, just so it compiles.
Thoughts anyone?
I did a little bit of research on this one, you are right GWT will look for all implementations of an Abstract class, if and only if, the AbstractClass is referenced in an RPC GWTAsync interface, even though some are in non-GWT packages.
Let's say an object of type AbstractClass comes in over the network, and the GWT deserializer is now tasked with coverting the network data into a specific instance. It needs to know about all implementations of AbstractClass, to find which is coming over the network right now! -- So to accomplish this it, at compiletime, generates a .rpc file for each GWT service interface, listing all possible concrete types that the service methods can return.
Ray Ryan (Google employee) once mentioned that it is a bad idea to use interfaces arguments or return types in any RPC interface. - because it makes it difficult for the deserializer to know the exact type.
You can hand edit the generated RPC file and remove the offending types, or mark the other implementations as Non Serializable by not implementing Serializable in those implementations in other packages.
A Better way could be - I suspect you wrote code : "implements java.io.Serializable" at the top level (for the AbstractClass itself), maybe it's now time to move it to each implementation.
Now the GWT RPC deserializer's task is clear and straightforward - it knows that only certain implementations (that are serializable) of the AbstractClass will come over the network, and reach and compile them only. So it will not compile the other non serializable subclassess of your AbstractClass - as it knows they arent serializable.
There is one more option : If as I suspect you are using the command pattern - I have seen all the abstract interfaces, super classes for Command and Response etc always go in the client side packages - i.e., those that are GWT compiled. They are referrable and usable and instantiable for the server end of the application - so these source files are compiled twice, once by GWT into javascript for browser usage, and once by javac into bytecode for allowing reference from serverside. Thus in all GWT modules, including gwt-user.jar if you open them with 7Zip or WinZip you will see source and class files JARed together.
I recommend Moving AbstractMessage into the models package - as it is the model QueryResponse's super class.
And also inhertance in models is only a good idea, if you have 0 fields and only methods(behaviour) in the super class.
Lastly, if GWT is to make your QueryResponse into javascript - it needs ALL Types mentioned in the source file, to compile properly. So do not mention any server-only-classes in a source file meant to become javascript.
Have a region that has all the server-side java classes that will be run in a JVM on the server, and another region full of source files that will be compiled into javascript by the GWT compiler. The server-side region code/classes CAN refer to client region code/classes but defenitely NOT the vice versa. Make sure that no code thats gonna become javascript is referring (even an unused import statement) to a server side class.
GWT compiler works with source files only, however you need to compile client code into .class files so your serverside classes can refer to them.
NEW EDIT :
I did a little bit of research on this one, you are right GWT will look for all implementations of an Abstract class, if and only if, the AbstractClass is referenced in an RPC GWTAsync interface, even though some are in non-GWT packages.
Let's say an object of type AbstractClass comes in over the network, and the GWT deserializer is now tasked with coverting the network data into a specific instance. It needs to know about all implementations of AbstractClass, to find which is coming over the network right now! -- So to accomplish this it, at compiletime, generates a .rpc file for each GWT service interface, listing all possible concrete types that the service methods can return.
Ray Ryan (Google employee) once mentioned that it is a bad idea to use interfaces arguments or return types in any RPC interface. - because it makes it difficult for the deserializer to know the exact type.
You can hand edit the generated RPC file and remove the offending types, or mark the other implementations as Non Serializable by not implementing Serializable in those implementations in other packages.
A Better way could be -
I suspect you wrote code : "implements java.io.Serializable" at the top level (for the AbstractClass itself), maybe it's now time to move it to each implementation.
Now the GWT RPC deserializer's task is clear and straightforward - it knows that only certain implementations (that are serializable) of the AbstractClass will come over the network, and reach and compile them only. So it will not compile the other non serializable subclassess of your AbstractClass - as it knows they arent serializable.
I have GWT project that uses Generators to create light dynamic reflection objects.
I was wondering if anybody knows of a way to determine whether or not a particular class is referenced in the dependency tree beginning at all EntryPoints. If I could do this, I could avoid generating reflection data for classes that will never be used anyway.
My understanding is that when GWT does its compiling, it performs a similar check so that it can reduce the total size of the compiled code, but I haven't been able to find any related methods in TypeOracle or anything like that.
This is an indirect method of accomplishing what you are getting at. I believe each GWT module, is fully packaged into a regular java package. You can use
TypeOracle.findPackage(String pkgName)
to get the JPackage instance, and on that instance you use findType(String typeName) to see if a type is present in that package. If present, its likely that it is referenced in some file and GWT will compile it.
There is also this method getPackages() which returns an array of all packages known to this type oracle - therefore reachable for GWT compiler.
JPackage[] getPackages()
You can iteratively findType() on each package to find if the type is going to be compiled or not.
The BEST method is to define a custom annotation and whitelist all the classes that you do want to generate reflection code. You can annotate the required classes with it, and checking for that presence of annotation before generating code for it.
My favorite is to follow a naming convention over annotation, (I did both together), and thus maintain a whitelist, and make the convention (its usually a REGEX) a "setting" that can be changed however the team wants.