How to prevent generic usage of a certain API (e.g Streaming API or Builder API) with ArchUnit? - archunit

Given a set of classes where it should not be forbidden to use certain APIs (for whatever reason).
For example, prohibiting Java 8 Streaming API, or calling a Builder inner class because you want to force the usage of loops and constructors for particular classes.
The critical part is that you do not know the ownerName beforehand and there is no callMethod(methodName) where I could coarse-grainy disallow calling stream() or build() methods.
Any ideas?

You can compose powerful ArchRules using predicates instead of the fluent API; in your case with
.callMethodWhere(DescribedPredicate<? super JavaMethodCall> predicate).
To prevent the usage of someCollection.stream(), you could start with HasName.Predicates.name:
noClasses().should().callMethodWhere(name("stream"))
To avoid false-positives, the rule should probably become more specific.
ArchUnit ships lots of useful pre-defined predicates; you just need to find them (and possibly deal with their covariant parameter types via DescribedPredicate.forSubtype):
noClasses().should().callMethodWhere(target(
name("stream").<CodeUnitCallTarget>forSubtype().and(
owner(assignableTo(Collection.class)).<CodeUnitCallTarget>forSubtype().and(
rawParameterTypes(new Class[0])
)
)
))
I personally find it simpler to define a custom predicate instead (e.g. using
DescribedPredicate.describe):
noClasses().should().callMethodWhere(target(describe("is Collection.stream()",
target -> "stream".equals(target.getName()) &&
target.getOwner().isAssignableTo(Collection.class) &&
target.getParameterTypes().isEmpty()
)))
FYI: My solution uses the following imports:
import static com.tngtech.archunit.base.DescribedPredicate.describe;
import static com.tngtech.archunit.core.domain.JavaCall.Predicates.target;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.assignableTo;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.name;
import static com.tngtech.archunit.core.domain.properties.HasOwner.Predicates.With.owner;
import static com.tngtech.archunit.core.domain.properties.HasParameterTypes.Predicates.rawParameterTypes;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;

Related

Switching multiple inheritance via mixins to composition but keep the same API

Firstly, thank you for taking the time to read and input. It is greatly appreciated.
Question: What kind of approach can we take to keep the same public API of a class currently using multiple mixins but refactor it internally to be composed of objects that do the same work as the mixin. Autocomplete is a must (so runtime dynamics are kind of out such as hacking things on via __getattr__ or similar - I know this depends on the runtime environment i.e ipython vs pycharm etc, for the sake of this question, assume pycharm which cannot leverage __dir__ I think fully.
Accompanying Information:
I am writing a little assertion library in python and I have a core class which is instantiated with a value and subsequently inherits various assertion capabilities against that value via a growing number of mixin classes:
class Asserto(StringMixin, RegexMixin):
def __init__(self, value: typing.Any, type_of: str = AssertTypes.HARD, description: typing.Optional[str] = None):
self.value = value
self.type_of = type_of
self.description = description
These mixin classes offer various assertion methods for particular types, here is a quick example of one:
from __future__ import annotations
class StringMixin:
def ends_with(self, suffix: str) -> StringMixin:
if not self.value.endswith(suffix):
self.error(f"{self.value} did not end with {suffix}")
def starts_with(self, prefix: str) -> StringMixin:
if not self.value.startswith(prefix):
self.error(f"{self.value} did not end with {prefix}")
I would like to refactor the Asserto class to compose itself of various implementations of some sort of Assertable interface rather than clobber together a god class here with Mixins, I'm likely to have 10+ Mixins by the time I am finished.
Is there a way to achieve the same public facing API as this mixins setup so that client code has access to everything through the Asserto(value).check_something(...) but using composition internally?
I could define every single method in the Asserto class that just delegate to the appropriate concrete obj internally but then I am just making a massive god class anyway and the composition feels like a pointless endeavour in that instance?
for example in client code, I'd like all the current mixins methods to be available on an Asserto instance with autocomplete.
def test_something():
Asserto("foo").ends_with("oo")
Thank you for your time. Perhaps using the mixin approach is the correct way here, but it feels kind of clunky.

Why is the usage of util.inherits() discouraged?

According to the Node.js documentation :
Note: usage of util.inherits() is discouraged. Please use the ES6 class and extends keywords to get language level inheritance support. Also note that the two styles are semantically incompatible.
https://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor
The reason why util.inherits is discouraged, is because changing the prototype of an object should be avoided, as most JavaScript engines look for optimisations assuming that the prototype will not change. When it does, this may lead to bad performance.
util.inherits relies on Object.setPrototypeOf to make this change, and the MDN documentation of that native method has this warning:
Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, currently a very slow operation in every browser and JavaScript engine. In addition, the effects of altering inheritance are subtle and far-flung, and are not limited to the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered.
Because this feature is a part of the language, it is still the burden on engine developers to implement that feature performantly (ideally). Until engine developers address this issue, if you are concerned about performance, you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().
As the quote says, you should use the ES6 class and extends keywords to get language level inheritance support instead of utils.inherits and that's exactly the reason for which to use it is discouraged: there exist better alternatives that are part of the core language, that's all.
util.inherits comes from the time when those utils were not part of the language and it requires you a lot of boilerplate to define your own inheritance tools.
Nowadays the language offers a valid alternative and it doesn't make sense anymore to use the ones provided with the library itself. Of course, this is true as long as you use plan to use ES6 - otherwise ignore that note and continue to use utils.inherits.
To reply to your comment:
How is util.inherits() more complicated?
It's not a matter of being more or less complicated. To use a core language feature should be ever your preferred way over using a library specific alternative for obvious reasons.
util.inherits() got deprecated in the new version of node so need to use the ES6 class and extends keywords to get language level inheritance support instead of utils.inherits.
below example which I gave below helps you to understand more clearly :
"use strict";
class Person {
constructor(fName, lName) {
this.firstName = fName;
this.lastName = lName;
}
greet() {
console.log("in a class fn..", this.firstName, "+ ", this.lastName);
}
}
class PoliceMan extends Person {
constructor(burgler) {
super("basava", "sk");
this.burgler = burgler;
}
}
let policeObj = new PoliceMan();
policeObj.greet();
Output : in a class fn.. basava + sk
Here we can see Person class is inherited by PoliceMan class, so that PoliceMan obj can access the properties of Person class by calling super(); in a constructor
Hope this will work as util.inherits();
Happy Coding !!!

JAXB XJC options: Alternative to com.sun.tools.xjc.Options which is Java9-friendly and OSGi-friendly

In our framework we have an interface with this method in the public API:
JaxbConfiguration newJaxbConfiguration(Options xjcOpts);
In the implementation, we do something like this:
import com.sun.tools.xjc.ModelLoader;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.model.Model;
...
public JaxbConfiguration newJaxbConfiguration(Options xjcOpts) {
Model model = ModelLoader.load(xjcOpts, ...);
...
}
However, both OSGi and Java 9's jigsaw don't like that we use com.sun.tools.xjc.Options, not in our implementation and especially not in our public API interface.
How can we get rid of it?
The JDeps website lists some of the JDK internal APIs and the recommended way to replace their usage. However, the use of ModelLoader.load() is not mentioned. My guess is that this use case has not come up enough to get the attention of the JDeps team.
My recommendation would be to refactor this method so that
you pass in the data you're using to construct the Options argument, instead of passing in the Options argument
use that data to construct your JaxbConfiguration object instead of converting from the internal Model.
You don't mention what JaxbConfiguration is or what library it's from so it's hard for me to say exactly how to construct it. Anyway, this answer is about how to remove the use of the internal API. How to construct a JaxbConfiguration is probably a different question.

How to provide and consume require.js modules in scala.js (and extending classes)

I'm doing this Ensime package for Atom.io https://github.com/ensime/ensime-atom and I've been thinking about the possibility to use scala.js instead of writing Coffeescript.
Atom is a web based editor which is scripted with js and is node.js based. A plugin/package defines it's main entry point by pointing out a javascript object with a few specific.
I figured I should start out simple and try using scala.js replacing the simplest coffeescript file I have:
{View} = require 'atom-space-pen-views'
# View for the little status messages down there where messages from Ensime server can be shown
module.exports =
class StatusbarView extends View
#content: ->
#div class: 'ensime-status inline-block'
initialize: ->
serialize: ->
init: ->
#attach()
attach: =>
statusbar = document.querySelector('status-bar')
statusbar?.addLeftTile {item: this}
setText: (text) =>
#text("Ensime: #{text}").show()
destroy: ->
#detach()
As you can see this exports a require.js module and is a class extending a class fetched with require as well.
Sooo.
I'm thinking I'd just use Dynamic for the require dep as I've seen on SO How to invoke nodejs modules from scala.js?:
import js.Dynamic.{global => g}
import js.DynamicImplicits._
private[views] object SpacePen {
private val spacePenViews = require("atom-space-pen-views")
val view = spacePenViews.view
}
But if I wanted to type the super-class, could I just make a facade-trait and do asInstanceOf?
Secondly, I wonder how I can export my class as a node module. I found this:
https://github.com/rockymadden/scala-node/blob/master/main/src/main/coffeescript/example.coffee
Is this the right way? Do I need to do the sandboxing? Couldn't I just get moduleimported from global and write module.exports = _some_scala_object_?
I'm also wondering how I could extend existing js classes. The same problem as asked here, but I don't really understand the answer:
https://groups.google.com/forum/#!topic/scala-js/l0gSOSiqubs
My code so far:
private[views] object SpacePen {
private val spacePenViews = js.Dynamic.global.require("atom-space-pen-views")
type View = spacePenViews.view
}
class StatusBarView extends SpacePen.View {
override def content =
super.div()
}
gives me compile errors that I can't extend sealed trait Dynamic. Of course.
Any pointers highly appreciated!
I'm not particularly expert in Node per se, but to answer your first question, yes -- if you have a pointer to a JS object, and you know the details of its type, you can pretty much always define a facade trait and asInstanceOf to use it. That ought to work.
As for the last bit, you basically can't extend JS classes in Scala.js -- it just doesn't work. The way most of us get around that is by defining implicit classes, or using implicit def's, to get the appearance of extending without actually doing so.
For example, given JS class Foo, I can write
implicit class RichFoo(foo:Foo) {
def method1() = { ... }
}
This is actually a wrapper around Foo, but calling code can simply call foo.method1() without worrying about that detail.
You can see this approach in action very heavily in jquery-facade, particularly in the relationship between JQuery (the pure facade), JQueryTyped (some tweaked methods over JQuery to make them work better in Scala), and JQueryExtensions (some higher-level functions built around JQuery). These are held together using implicit def's in package.scala. As far as calling code is concerned, all of these simply look like methods on JQuery.

solving multiple inheritance (for precooked classes)

What I need: a class with two parents, which are ContextBoundObject and another class.
Why: I need to access the ContextBoundOject to log the method calls.
Composition works? As of now, no (types are not recognized, among other things).
Are other ways to do this? Yes, but not so automatable and without third-party components (maybe a T4 could do, but I'm no expert).
A more detailed explanation.
I need to extend System classes (some of which have already MarshalByRefObject (which is the parent of ContextBoundObject) for parent, for example ServiceBase and FileSystemWatcher, and some not, for example Exception and Timer) to access some inner workings of the framework, so I can log method calls (for now; in future it may change).
If I use this way I only have to add a class name to the object I want to log, instead of adding the logging calls to every method, but obviously I can't do this:
public class MyService:ServiceBase,ContextBoundObject,IDisposable{
public MyService(){}
public Dispose(){}
}
so one could try the usual solution, interfaces, but then if I call Run as in:
ServiceBase.Run(new MyService());
using a hypotethical interface IServiceBase it wouldn't work, because the type ServiceBase is not castable to IServiceBase -- it doesn't inherit from any interface. The problem is even worse with exceptions: throw only accepts a type descending from Exception.
The reverse, producing a IContextBoundObject interface, doesn't seem to work either: the logging mechanism doesn't work by methods, so I don't need to implement any, just an attribute and some small internal classes (and inheriting from ContextBoundObject, not even from MarshalByRefObject, which the metadata present as practically the same).
From what I see, extending from ContextBoundObject puts the extended class in a Proxy (probably because in this way the method calls use SyncProcessMessage(IMessage) and so can be intercepted and logged), maybe there's a way to do it without inheritance, or maybe there could be pre or post compiling techniques available for surrounding methods with logging calls (like T4 Text Templates), I don't know.
If someone wants to give this a look, I used a customized version of MSTestExtentions in my program to do the logging (of the method calls).
Any ideas are appreciated. There could be the need for more explanations, just ask.
Logging method calls is usually done using attributes to annotate classes or methods for which you want to have logging enabled. This is called Aspect Oriented Programming.
For this to work, you need a software that understands those attributes and post-processes your assembly by adding the necessary code to the methods / classes that have been annotated.
For C# there exists PostSharp. See here for an introduction.
Experimenting with proxies I found a way that apparently logs explicit calls.
Essentially I create a RealProxy like in example in the msdn, then obtain the TransparentProxy and use that as the normal object.
The logging is done in the Invoke method overridden in the customized RealProxy class.
static void Main(){
...
var ServiceClassProxy=new ServiceRealProxy(typeof(AServiceBaseClass),new object[]{/*args*/});
aServiceInstance=(AServiceBaseClass)ServiceClassProxy.GetTransparentProxy();
ServiceBase.Run(aServiceInstance);
...
}
In the proxy class the Invoke will be done like this:
class ServiceRealProxy:RealProxy{
...
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
public override IMessage Invoke(IMessage myIMessage){
// remember to set the "__Uri" property you get in the constructor
...
/* logging before */
myReturnMessage = ChannelServices.SyncDispatchMessage(myIMessage);
/* logging after */
...
return myReturnMessage;
// it could be useful making a switch for all the derived types from IMessage; I see 18 of them, from
// System.Runtime.Remoting.Messaging.ConstructionCall
// ... to
// System.Runtime.Remoting.Messaging.TransitionCall
}
...
}
I have still to investigate extensively, but the logging happened. This isn't an answer to my original problem because I have still to test this on classes that don't inherit from MarshalByRefObject.

Resources