Is there any way of inserting code at runtime to log return values, for instance, using instrumentation?
So far, I managed to insert code when a method exits, but I would like to log something like "method foo returned HashMap { 1 -> 2, 2 -> 3 }"
I'm looking for a general approach that can also deal with, for instance, java.io.* classes. (So in general I'll have no access to the code).
I tried using a custom classloader too, but lot of difficulties arise as I cannot modify java.* classes.
Thanks for the help!
Sergio
Check out BTrace. It's Java, and I believe it'll do what you want.
Have you considered AOP? (Aspect-oriented programming) - if by "I cannot modify java.* classes" you mean you don't have access to the uncompiled code, and cannot add configuration, etc., then that won't probably work for you. In any other case, check that link for examples using Spring-aop:
http://static.springsource.org/spring/docs/2.5.x/reference/aop.html
If not, you could consider solutions based on remote-debugging, or profiling. But they all involve "some" access to the original code, if only to enable / disable JMX access.
Well, since you're looking for everything, the only thing I can think off is using a machine agent. Machine agents hook into the low levels of the JVM itself and can be used to monitor these things.
I have not used DTrace, but it sounds like it would be able to do what you need. Adam Leventhal wrote a nice blog post about it. The link to DTrace in the blog is broken, but I'm sure a quick search and you'll come up with it.
Take a look at Spring AOP, which is quite powerful, and flexible. To start you off on the method foo, you can apply an AfterReturning advice to it as:
#Aspect
public class AfterReturningExample {
#AfterReturning(
pointcut="package.of.your.choice.YourClassName.foo()",
returning="retVal")
public void logTheFoo( Object retVal ) {
// ... logger.trace( "method 'foo' returned " + retVal ); // might need to convert "retVal" toString representation if needed
}
}
The pointcut syntax is really flexible so you can target all the sub packages, components, methods, return values given the expression.
Is there a name for the style of API that reads like a sentence? For example, in google-guice
bind(TransactionLog.class).to(DatabaseTransactionLog.class);
or in Easymock
expect(mock.voteForRemoval("Document")).andReturn((byte) 42);
I want to program an api that looks similar to what I call the 'google style' api, i.e. I want it to look like:
RowStyle(RED_BACKGROUND).when(PROP_ERROR_MESSAGE).notNull();
and would like to know pros/cons to this type of API, if it has a name, and how you would go about implementing it.
Those APIs are called "fluent API" and in our days some guys call them "internal DSL", but the first term is AFAICT more widely used (and is the older correct term).
For me, this will only work if the sequence of those operations (style(), when(), notNull() ) is strictly defined. If you can call when() after notNull(), this won't make any sence.
Normally, you just define a method with several parameters:
public void rowStyle(String condition, boolean notNull)
, but these additional calls are the good way to specify optional parameters.
So, + if you have optional parameters, - if you don't have them; + if strictly defined call sequence, - if not.
Sometime ago, I remember being told not to use numbers in Java method names. Recently, I had a colleague ask me why and, for the life of me, I could not remember.
According to Sun (and now Oracle) the general naming convention for method names is:
Methods should be verbs, in mixed case
with the first letter lowercase, with
the first letter of each internal word
capitalized.
Code Conventions of Java
This doesn't specifically say that numbers can't be used, although by omission you can see that it's not advised.
Consider the situatiuon (that my colleague has) where you want to perform some logic based on a specific year, for instance, a new policy that takes affect in 2011, and so your application must act on the information and process it based on it's year. Common sense could tell you that you could call the method:
boolean isSessionPost2011(int id) {}
Is it acceptable to use numbers in method names (despite the wording of the standard)? If not, why?
Edit: "This doesn't specifically say that numbers can't be used, although by omission you can see that it's not advised." Perhaps I worded this incorrectly. The standard says 'Methods should be verbs'. I read this to say that considering a number is not a verb, then method names should not use numbers.
The standard Java class library is full of classes and methods with numbers in it, like Graphics2D.
The method seems ... overly specific.
Couldn't you instead use:
boolean isSessionAfter(int id, Date date)
?
That way the next time you have a policy applied to anything after a particular date, you don't need to copy-paste the old method and change the number - you just call it with a different date.
Sure, it's acceptable to use numbers in method names. But as per your example, that's why it's generally frowned upon. Let's say that there is now a new policy in place for the year 2012. Now, there's a new policy in place for 2014. And maybe 2020! So, you have four methods that are roughly equivalent.
What you want isn't a boolean but rather a strategy to do something, or do nothing, based on whether or not a policy was found. Hence, a method void processPolicy(Structure yourStructure); would be a better approach - now you can shield that you're doing a lookup based on the year, and don't have to have separate methods per year, or even limit it to just one policy per year (maybe a policy takes place in two different years, for example, or just three months).
The Java Language Specification seems fairly specific on this topic:
3.8 Identifiers
An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter.
...
The Java letters include uppercase and lowercase ASCII Latin letters A-Z (\u0041-\u005a), and a-z (\u0061-\u007a), and, for historical reasons, the ASCII underscore (_, or \u005f) and dollar sign ($, or \u0024). The $ character should be used only in mechanically generated source code or, rarely, to access preexisting names on legacy systems.
The "Java digits" include the ASCII digits 0-9 (\u0030-\u0039).
This doesn't specifically say that numbers can't be used, although by omission you can see that it's not advised.
I certainly wouldn't read the Java Style Guide that way. And judging from numerous examples in the Java class libraries, neither do they.
I guess the only caveat is that the JSG recommends use of meaningful names. And the corollary is that you should only use numbers in identifiers when they are semantically meaningful. Good examples are
"3D",
"i18n" ( == internationalization ),
"2020" (the year),
"X509" (a standard), and so on.
Even "int2Real" is meaningful in a folksy way.
UPDATE
#biziclomp has raised the case of LayoutManager2, and claims that the 2 conveys no meaning.
Here's what the javadoc says about the purpose of this interface:
This minimal extension to LayoutManager is intended for tool providers who wish to the creation of constraint-based layouts. It does not yet provide full, general support for custom constraint-based layout managers.
From this, I would say that the 2 in the name is meaningful. Basically, it is saying that you can view this as a successor to LayoutManager. I guess that could have been said in words, but see the examples above on how numbers where numbers are used as short-hand.
# BlueRaja writes:
The 2 does not explain anything - how is LayoutManager2 any different from LayoutManager?
The advice of the Style Guide is NOT that names should explain things. Rather, it advises that they should be meaningful. (For the explanation, refer to the javadoc.) Obviously meaningfulness is relative, but there is a practical limit on the amount of information you can put into an identifier before it becomes hard to read and hard to type.
My take is that the identifier should remind the reader what the meaning of the thing (class, field, method, etc) that is named.
It is a trade-off.
Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized.
This phrasing alone already shows that they use a more general meaning of verb than the usual, where only is would be the verb, neither session nor post are verbs. The sentence means something like Method names should be verbs or verbal phrases, ..., and numbers can very well be parts of verbal phrases.
The idea is that a complete method call can be read as a complete sentence, with the subject being the object before the dot, the verb being the method name, and additional objects being the arguments to the method:
if (buffer.isEmpty())
buffer.append(word);
(Most such sentences would be either questioning or imperative ones.)
Your method name has (from a naming convention viewpoint) the only problem that the subject of the sentence (the session) is not the this object of your method, but an parameter, but this can't be avoided with Java, I think (please someone prove me wrong).
For multiple-parameter methods the smalltalk approach would work better:
"Hello" replace: "e" with: "x"
(where replace:with: is one method of the string class.)
Yes, in some circumstances. For example, maybe you want to handle X.509 certificates. I think it would be perfectly acceptable to write a method called handleX509Certificate.
The only problem I see with using numbers in method names is that it may be an indication that something in your design could be improved upon. (I hesitate to say "is wrong.") For instance, in your example, you stated that you have a specific policy which comes into effect after 2011. However, having a method specifically to check for that year seems overly specific and magic-number-y. I'd instead suggest creating a generalized function to check if an event occurred after a specified date as Anon suggested.
(Anon's answer popped up while I was halfway through mine, so my apologies if it seems like I'm just duplicating what he said. I felt that mine expanded on what he was saying a bit, so I thought I'd post it anyway.)
I would consider calling your method something else. Nothing against numbers exactly, but what happens if the project slips it release date? You'll have a method called post2011 - when it should be called post2012 now. Consider calling it postProjNameImplentation instead maybe?
The use of number it is not bad itself, but usually they are not very common.
in the specific case, I don't think isSessionPost2011(int id) {} is a good name. but it is better isSessionPostYear(int id, int year) {} more extensible for future uses.
The fact it is a coding convention and the use of the verb "should" suggest you that digits are permitted but advised against in methods names. However in your example, why not generalizing the same code as?
session.isPostYear(int year);
We use 'em all the time, like the example you showed. Also for interface versions, like IConnection2 and IConnection3.
Eclipse doesn't complain that it's a nontraditional name, either. :)
But acceptable? That's kind-of up to you.
Don't ever forget - rules are made to be broken. The only absolute should be that there are no absolutes.
I don't believe there's a per se reason to avoid numbers in identifiers, although in the case you describe, I don't know that I'd use it. Rather, I'd name the method something like boolean isPolicyXyzApplicable(int id).
If this is a policy that's expected to change more over time, consider splitting policies out into different classes so you don't end up growing a long vine of if(isPolicyX) ... else if(isPolicyY) ... else if(isPolicyZ) ... in your methods. Once this is factored out, use an abstract or interface method Policy.isApplicableTo(transaction) and a collection of Policy objects to determine what to do.
As long as you have a reason for using numbers, then imho I think it's fine.
For your example, there might be 2 isSessionPost method, so how would you name them? isSessionPost and isSessionPost2? Not very clear to be honest.
Just remember that all names must be meaningful and you won't go wrong.
I think in your case it's OK to use it as a one-off marker, specifically if you expect that the method will only live for a short period of time and eventually be deprecated.
If I understand your use case, you need to bring in some legacy data into the new version of your application. If this is the case, then definitely add this method, mark it #deprecated and retire it when all your clients are updated.
On the other hand Ralph here has a valid point. Don't let this project to slip into 2012 :)
nothing is wrong
String int2string(int i)
User findUser4Id(long id)
void startHibern8();
wow! this website doesn't like these method names! I got captchaed!
In Java, is there a semantic difference between using "Illegal" (as in IllegalArgumentException) versus "Invalid" (as in javax.activity.InvalidActivityException)?
During the course of an assignment it became useful to write a subclass of IllegalArgumentException to represent a series of input characters that cannot be tokenized, and I'm wondering whether convention says to use InvalidTokenException or IllegalTokenException.
The only difference I can find so far is that java.lang seems to prefer "Illegal" while javax.* prefers "Invalid". However, there is also java.security.InvalidParameterException which is a subclass of IllegalArgumentException.
You can have legal usage of an API and still have invalid data; it is all semantics.
javax.activity.InvalidActivityException is inherited from java.rmi.RemoteException and you probably don't want this dependency. See also Javadoc
EDIT both Invalid and Illegal are used synonymously it makes no differency in semantics, just the technical issues mentioned above.
EDIT: From Postgres Documentation Section 45.3.14. Tricky words to avoid:
Illegal. "Illegal" stands for a violation of the law, the rest is "invalid". Better yet, say why it's invalid.
AFAIK, IllegalArgumentException should only be used when you want to signal the incorrect use of an API method call. What it appears you are describing is a scenario when the API has been used incorrectly, so I think an IllegalArgumentException would be the better choice.
combining closures (FCM) and generics, would it be possible to have fully type-safe criteria.
// The following works without a cast as Foo.id is a 'long' field.
List<Long> ids = session.createCriteria(Foo.class)
.setProjection(Foo#id)
.list();
// The following is a compilation error, as Foo.bar is defined as an int, and not a string
session.createCriteria(Foo.class)
.addRestriction(Restrictions.eq(Foo#bar,"blah"))
.list();
I've read the JPA 2.0 spec for type-safe criteria. But its still somewhat lacking.
Besides, I'm just using criteria here as an example of improving the type-safety of code in general. I used the static typing of java heavily to let me code faster. But as a result I get bitten now and then by the parts of my code that ignore typing. For example HQL queries.
The code you're describing does not use closures but field literals (method literals). Like the good old class literal. These could help in a criteria API. The JPA 2 source code generation work-around for a type-safe query interface could be replaced with it. If it will be part of JDK7.
As Thomas points out, this doesn't strictly require closures. It's all up in the air at the moment, given no-one knows quite what proposal is being looked at. It's not clear if FCM is actually the basis of the proposal, particularly given that Stephen Colebourne seemed to be as susprised as anyone about the announcement.
A lot of people are pointing at Neal Gafter's mysteriously-revised-more-or-less-right-as-the-Devoxx-presentation-announcing-closures-was-being-given spec as a hint as to what form closures might take. Mind you, the revised proposal looks (aesthetically) rather like FCM!
That spec does include the kind of references you refer to (under 'Method References' in the above line), and of course FCM has the same. Yes, this would definitely make you suggest possible. My very first thought when reading about this was how it would affect JPA/Hibernate, and/or our own abstraction layers around same, in this regard. Typesafe, refactorable method references in your criteria? Hell yeah.