Editor's note: Sometimes the most interesting discussions begin when someone says, "This may be a stupid question, but ...." If the person asking the question has taken the time to think about the problem before asking, the question is often not stupid at all. The uncertainty points out an ambiguity in the specs, holes in the docs, or a search for how more experienced programmers might address a particular problem. From time to time, we will print one of the "(Not So) Stupid Questions" we receive and invite our readers to answer the question in the feedback section.
Remember that new people are joining the Java community all the time and may be looking for help from those with more experience. Also, those who began with Java as their first language can benefit from those coming to the community with experience in other languages. As always, answer the questions with kindness. You are also welcome to submit your questions to .
This may be a stupid question, but ... "What do you do when you want to avoid any calls from inside your own methods to outside classes?"
First Thoughts
We can define a method private. This is a protection against calls from outside of the class declaring this method. But what do you do when you want to avoid any calls from inside the method to any outside class, other than maybe to the java.lang classes that are fundamental to almost any application?
Why would you want to do this? And why wouldn't it be enough to say, "If you don't want your methods to make outside calls, then just don't make any?" Let me explain.
What I want is to prohibit my own method from calling any other outside class, specifically, to be able to declare calling grants. This idea comes from both practical needs and theoretical ideas:
Practical because sometimes I have to refactor code that lacks maturity or polish. I need to eliminate dependencies, and that means reining in outside calls. I also want to eliminate cyclic dependencies, where class A calls class B, and class B calls A.
When a project is complex, we need a lot of protection from ourselves. I would appreciate such protection if I were coding a space shuttle navigation program, for instance. I imagine the astronauts would like it too.
The idea has a theoretical basis, too, because I'm studying the science of systems (cybernetics) that describes their structuration and communication. And I think that our modeling approach (OO from OMG and more Java) doesn't match a typical system model. Of course, I'm not an expert, so maybe I'm mistaken.
A system (or subsystem) is able to protect its state and structuration from the context. It's what we have with the encapsulation (getters, setters, private modifiers, etc.).
And a system manages its communication using ports that can receive and send message to the context. These ports can be open or closed and can select messages (like on network architecture). We can create methods on a class that look like ports, with combination of getters/setters, an observable-observer pattern, etc. Some methods are dedicated to the communication with other functional classes in our program--but others exist only to recompute the state of the class, or perform operations like computing a mathematical function.
These latter methods shouldn't call anything else, except perhaps some some java.* packages and objects from the business logic layer of my application.
I hope I've been clear enough. I would like to now what Java developers and modeling specialists think about this idea:
Eve Online ISK (The Inter Stellar Currency) is the currency in Eve. The value of EVE Online ISK goes up and down according to the demand and supply rules. EVE Online ISK can be earned by usual mining, running trade route and manufacturing ships. Some optional ways to earn EVE Online ISK are guarding miner or trade runner in deep space or hunting down pirates and claiming the bounty. Others prefer the opposite, being the pirates themselves and earn more lucrative income. Players spend eve isk to get
Chinese antique furniture has a long history. Especially in the late Ming and early Qing dynasties, it had reached a high level.and we car supplycar wash equipment
The cabinets of Chinese antique furniture have many kinds of style. For the big cabinet can be used as wardrobe. When you open the door, you can put your cloth in it. When you close it, it is an art. The middle size cabinet, it has many shelves and drawers, you can put it in your kitchen as a sideboard, especial, it is easy to clean. Small cabinet is very suit for the space of your bedside with good looking.
The people has begin to realize the value of old furniture. From antique cabinets, we can mostly find the content of Chinese antique furniture and history
You can't directly do this in the languagel you could put something together using reflection and runtime checking, but it would be a hack- an ugly hack.
So the language doesn't do this, really. Is that a bad thing? No.
You have some idea . maybe a good one, that you don't want your methods to do X- in this case X is - talk to anyone outside themselves.
Tomorrow, someone comes up with a higher-level idea involving something even more sophisticated.
They decide that it would be great if we could specify some classes to be of two certain types FOO and BAR and these classes bear the relation to each other, called BAZ if and only if (iff) certain properties or other relations hold true involving these classes.
If FOO and BAR stand in relation BAZ to each other, then they can't invoke each other's methods.
Think of the things you could do with that. !! Or just pretend it's the most wonderful thing in the world for Special Progammer Y.
The problem with this is, you're programming by another name.
You're offloading some of the custom logic of your program onto the language.
But a general purpose programming language is not going to very attractive (read: useful, read: popular) if it gets reengineered to fit every model like this that comes along.
If Sun did this, or people thought Sun was prone to doing things like this, they'd stop using Java. No one would trust where it would be tomorrow. You investment in learning the language would be too easily bankruptable.
Even is you could specify this in code, the best you would get would be a compiler error. There are still runtime errors to be had involving runtime assignment of type.
So you'd get a compiler error at best.
Just program. Some things are so popular, they get turned into libraries. Some other things are so important, people develop special tools to deal with those issues. But the programming language at core is always going to be more basic than the purpose you want to put it to.
We call that a good programming language.
You can't
2007-08-29 00:26:52 alec6
[Reply | View]
I agree that we don't want to see the Java langage get an anarchical evolution, each time someone like me have a new (not so new I think) idea.
But I wouldn't like it to keep so basic, just responding to OO paradigm. OO paradigm is and old concept that perform a nice structuration of programs and that is close to our way of thinking and modelize. A world maid of Objects that interacts.
If there is new paradigm I think it's the role of the langage to help us to deal with it. That is what Java does with OO and what C doesn't. OO is just a meta level on data, then Cybernetics is a meta level on OO etc..; OO put in a box data and operations on; Cybernetics put in a box objects and interactions and deal with evolution of the system (in fact I would like an intelligent package system)
Once more: no arnarchical evolution !
A bizzare thought
2007-08-23 13:58:13 sfitzjava
[Reply | View]
What about taking the concept of the singleton pattern, but instead of protecting the instance by setting the constructor private what if you provided a proxy back.
So what you have is all your methods private, the class has a getInstance() method that creates a new instance, and wraps it with a invocationhandler. The invocation handler uses an interface to provide the various method signatures, but then you handle your control allowing or turning off access and from which classes.
It's much like the AOP suggestions to a degree, but your class is providing the invocation reference as an innerclass and can control access to the methods.
Understanding and managing your dependencies is a great thing to do. Architectural checkers such as macker (http://innig.net/macker/faq.html) can help you with this.
I don't think JDepend would be able to flag unwanted use of one class from another within the same package, but it could fit the bill otherwise (assuming you're unit testing anyway). If you're not unit testing, then you should know that using dependency injection will make that job quite a bit easier.
To go on with my thoughts
2007-08-21 05:51:51 alec6
[Reply | View]
All your suggestions are very interesting.
I'm trying to model the basis of a system. That personal research lead me to many questions, and so this one.
Off course I can be robust just by using the Java encapsulation system, end of course I use an Event Driven architecture to manage communication.
But I have the feeling that there is missing something to model systems with the OO paradigm. OO paradigm is good to model classification of objects (in the same box we put variables and operators on this ones). But it's seem not well done to model systems and systems interaction.
As an example, properties of classes have no distinction: some are for the aggregation of multiple parts of the component (GUI as usual), the class represents, some others are about states of the component; A TV class should have a Screen attribute and a state: on-off. But the state of the TV class depends on the state of it's components. The state attributes should launch event, not other ones.
What is a mess, (I think), is that Java doesn't give us the way to describe all of this in our programs, with special type (like enumeration, what about system) or key words (like private).
I hope that the Java experts will mind about the system paradigm.
Thanks for your advices.
To go on with my thoughts
2007-08-23 06:01:28 andyd
[Reply | View]
i'm confused. What exactly do you define as a 'system' in this case? I good article would help me understand where you are coming from and what you would like to do
Thanks
Andy
Second vote for design
2007-08-19 17:33:42 rickcarson
[Reply | View]
All the other suggestions seem to involve enormous amounts of work.
Essentially what you do is to divide up the application into logical chunks of functionality (e.g. all the database stuff in one place). Then wrap an interface around that group. That interface is _very_ public, which means that people can trust it not to change without being told about it, but that if two people working on different logical chunks discover they need to exchange some information, then that can be added to the interfaces without massive drama or ceremony, just talk about it so everyone knows.
You can apply the same principle to sub-chunks of the larger chunks.
Now why this is relevant to your scenario is that basically none of the classes need to be public. You can enforce that informally or formally. But it means that whatever goes on behind the interface is hidden (it becomes a facade of sorts), and so you can refactor away to your hearts content, without stuffing up everyone else's code.
NB: segmenting the application like this will also make testing _much_ easier.
Of course you need to get at the concrete instantiations of the class that backs the interface, so you can either go with dependency injection (at significant effort, reducing the ease of testing and risk of spaghetti configuration), or just write your own 'one true class' that builds the rest of the application. It is dead easy, and you probably already have one (unless it is a web app), since you would already have a class that has a main method that builds the rest of the app.
1) knit together annotations and a fancy classloader
2) there's this free eclipse plugin "semmlecode" that might be promising. It seems a lot easier to get started with than the other static analysis tools because I think your rules are entirely declarative.
Control Build Order and Classpath
2007-08-16 19:44:06 dwalend
[Reply | View]
It's terribly pragmatic, but we use build order and classpaths to control this sort of dependency.
First, we break our source code into subprojects built in a specific order. Earlier subprojects can't see code from later projects. It hasn't been compiled.
Second, we take control of the class path. If code in a subproject isn't supposed to directly use classes in another subproject, they don't appear in the compiler's classpath.
The tactic does a very good job of preventing crossed dependencies and controlling scope. The only glitch is that Eclipse users get bitten on occasion. (Eclipse takes control of the build order for itself and just builds everything whenever it chooses.)
Control Build Order and Classpath
2007-08-16 19:36:15 dwalend
[Reply | View]
It's terribly pragmatic, but we use build order and classpaths to control this sort of dependency.
First, we break our source code into subprojects built in a specific order. Earlier subprojects can't see code from later projects. It hasn't been compiled.
Second, we take control of the class path. If code in a subproject isn't supposed to directly use classes in another subproject, they don't appear in the compiler's classpath.
The tactic does a very good job of preventing crossed dependencies and controlling scope. The only glitch is that Eclipse users get bitten on occasion. (Eclipse takes control of the build order for itself and just builds everything whenever it chooses.)
What about AOP or annotations?
2007-08-16 14:52:19 xaxi
[Reply | View]
I got two alternatives:
AOP
You could define 'rules' about the types that can invoke methods on certain classes.
An aspect loads those rules and then is associated with a pointcut (one that matches the method invocations we want to avoid),
then the aspect deals with which invocation is allowed. The aspect denies o grant the method invocation.
This approach has a drawback, the rules would be applied at runtime.
Annotations
You could mark the classes you want to prohibit from calling methods with an annotation, next build an annotation
processor, then apply it on the source code. That way, the processor would detect the forbidden method invocations
and could issue warnings or errors.
You could use AspectJ's feature to declare compiler warnings or errors. Mark your methods with a custom annotations, e.g. @Unsafe and create a according pointcut that matches all calls of annotated methods to external classes. When you are using AJDT in Eclipse you will see these warnings directly in the IDE. If you declare it as errors it even disallows the compilation of your class.
The only thing that occurs to me would be to do something relatively fancy (and inconvenient) with Policy files and Permissions. This approach may be filled with holes, but it's the only thing I can think of.
To do this, you would have to put up with an awful lot of inconveniences:
Think backwards. Think about the methods that you are calling into. At the top of such methods, do an AccessController.checkPermission() call to see if the current call stack is granted the ability to call the method.
Of course if you do that, then you need to make sure that your private/package methods, or whatever they are, are able to be separated out by the Policy machinery so that you can restrict their permissions. Offhand I'm not sure of the best way to do this; locating them in a different place/jar file/CodeSource is the one that comes to mind, but now I'm really wandering off into the weeds.
Note that to do this you don't need a SecurityManager to be installed (anyone, any time, can call AccessManager.checkPermission()), but it might be helpful, because some Java internals check for its presence to see if "security is on".
Like I said, I'm sure there are all sorts of problems in here, but I believe this is the only mechanism--short of code conventions or AOP or something else that you come up with--that is available to you.
Short of some kind of bytecode rewriting or static analysis tool, I suspect the only way to isolate a class from the outside world using only standard Java constructs is to load it up in it's own class loader and set up a security manager that disallows access to anything outside of that class. (you'll probably still need to allow java.lang.*, of course, if only to use Strings).
Time for design
2007-08-16 08:27:27 sfitzjava
[Reply | View]
It sounds like taking a bit more time to design would be the answer, however it sounds like IOC or Injection might serve your needs.
However if you have a method that needs data that is not there at the time it's executing you must wait for it to be supplied (a performance issue), call to get it (breaks your requirements), or maybe posting an event and using EDA (event driven architecture) might work.
If you look at microbus.dev.java.net, I put together a library which I've found good for separation of calls between layers of design, and might fit your needs.
However I would still say spend more time doing a design, than trying to find a framework that does some magic so you don't need to define solid API's. (maybe I missed the point, but it sound like a red-herring.)
Like Albert Einstein said "make it as simple as possible, but no simpler." :)
Regards,
-Shawn
Time for design
2007-08-20 16:28:46 andyd
[Reply | View]
Hi
Its an interesting question to ask
I'm wondering. Why are you trying to pack everything into one class (by removing all the dependancies?)
and what would you like to see if happens if a method calls another method outside the class?
Normally, overloading a class with too much functionality makes the class too complicated and difficult to understand.
This is the single responsible principle. It's normally a good principle to stick to.
If i understand you correctly, then I think that you're looking for self contained lumps of code that can
exist independantly of each other. The 'system' is a set of these lumps that interact together. If that's the case then
you're looking at the concept of a component. A component is normally a set of classes that form an unit (lump) of
independant code that doesn't rely on another component. For example, in the nasa case, the components could be:
JoyStick (which deals with the joystick input and transalates it to a message), blackbox (that records the joystick
movements), etc. Each of these components would be composed of lots of classes. For example, the blackbox would
need classes for database transaction management (to store the data)
To get these components to interact, you'll need to send messages between them. As Shawn mentioned, a decend
architecure is needed so that this can happend. Even driven programming is a good approach (as shawn mantioned)