Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I wonder if anyone uses commercial/free java obfuscators on his own commercial product. I know only about one project that actually had an obfuscating step in the ant build step for releases.
Do you obfuscate? And if so, why do you obfuscate?
Is it really a way to protect the code or is it just a better feeling for the developers/managers?
edit: Ok, I to be exact about my point: Do you obfuscate to protect your IP (your algorithms, the work you've put into your product)? I won't obfuscate for security reasons, that doesn't feel right. So I'm only talking about protecting your applications code against competitors.
#staffan has a good point:
The reason to stay away from chaining code flow is that some of those changes makes it impossible for the JVM to efficiently optimize the code. In effect it will actually degrade the performance of your application.
If you do obfuscate, stay away from obfuscators that modify the code by changing code flow and/or adding exception blocks and such to make it hard to disassemble it. To make the code unreadable it is usually enough to just change all names of methods, fields and classes.
The reason to stay away from changing code flow is that some of those changes makes it impossible for the JVM to efficiently optimize the code. In effect it will actually degrade the performance of your application.
I think that the old (classical) way of the obfuscation is gradually losing its relevance. Because in most cases a classical obfuscators breaking a stack trace (it is not good for support your clients)
Nowadays the main point to not protect some algorithms, but to protect a sensitive data: API logins/passwords/keys, code which responsible for licensing (piracy still here, especially Western Europe, Russia, Asia, IMHO), advertisement account IDs, etc.
Interesting fact: we have all this sensitive data in Strings. Actually Strings is about 50-80% of logic of our applications.
It seems to me that future of obfuscation is "String encryption tools".
But now "String encryption" feature is available only in commercial obfuscators, such as: Allatori, Zelix KlassMaster, Smokescreen, Stringer Java Obfuscation Toolkit, DashO.
N.B.
I'm CEO at Licel LLC. Developer of Stringer Java Obfuscator.
I use proguard for JavaME development. It's not only very very good at making jar files smaller (Essential for mobile) but it is useful as a nicer way of doing device-specific code without resorting to IDE-unfriendly preprocessing tools such as antenna.
E.g.
public void doSomething()
{
/* Generated config class containing static finals: */
if (Configuration.ISMOTOROLA)
{
System.out.println("This is a motorola phone");
}
else
{
System.out.println("This is not a motorola phone");
}
}
This gets compiled, obfuscated, and the class file ends up as though you had written:
public void doSomething()
{
System.out.println("This is a motorola phone");
}
So you can have variants of code to work around manufacturer bugs in JVM/library implementations without bulking out the final executable class files.
I believe that some commercial obfuscators can also merge class files together in certain cases. This is useful because the more classes you have, the larger the size overhead you have in the zip (jar) file.
I spent some time this year trying out various Java obfuscators, and I found one to be miles ahead of the rest: JBCO. It's unfortunately a bit cumbersome to set up, and has no GUI, but in terms of the level of obfuscation it produces, it is unparalleled. You try feeding it a simple loop, and if your decompiler doesn't crash trying to load it, you will see something like this:
if(i < ll1) goto _L6; else goto _L5
_L5:
char ac[] = run(stop(lI1l));
l7 = (long)ac.length << 32 & 0xffffffff00000000L ^ l7 & 0xffffffffL;
if((int)((l7 & 0xffffffff00000000L) >> 32) != $5$)
{
l = (long)III << 50 & 0x4000000000000L ^ l & 0xfffbffffffffffffL;
} else
{
for(l3 = (long)III & 0xffffffffL ^ l3 & 0xffffffff00000000L; (int)(l3 & 0xffffffffL) < ll1; l3 = (long)(S$$ + (int)(l3 & 0xffffffffL)) ^ l3 & 0xffffffff00000000L)
{
for(int j = III; j < ll1; j++)
{
l2 = (long)actionevent[j][(int)(l3 & 0xffffffffL)] & 65535L ^ l2 & 0xffffffffffff0000L;
l6 = (long)(j << -351) & 0xffffffffL ^ l6 & 0xffffffff00000000L;
l1 = (long)((int)(l6 & 0xffffffffL) + j) & 0xffffffffL ^ l1 & 0xffffffff00000000L;
l = (long)((int)(l1 & 0xffffffffL) + (int)(l3 & 0xffffffffL)) << 16 & 0xffffffff0000L ^ l & 0xffff00000000ffffL;
l = (long)ac[(int)((l & 0xffffffff0000L) >> 16)] & 65535L ^ l & 0xffffffffffff0000L;
if((char)(int)(l2 & 65535L) != (char)(int)(l & 65535L))
{
l = (long)III << 50 & 0x4000000000000L ^ l & 0xfffbffffffffffffL;
}
}
}
}
You didn't know Java had goto's? Well, the JVM supports them =)
I use ProGuard and highly recommend it. While obfuscation does protect your code from casual attackers, it's main benefit is the minimizing effect of removing unused classes and methods and shortening all identifiers to 1 or 2 characters.
I think that for the most part obfuscation is pointless: even with full source code it's generally hard enough to figure out what the heck intention was (assuming there are no comments, and no meaningful names for local variables -- which is the case when re-generating sources from byte code). Obfuscation just decorates the cake.
I think developers and especially their managers tend to greatly over-exaggerate risk of someone seeing the source code. While good decompilers can produce nice looking source code, it's not trivial to work with it, and costs associated (not to mention legal risks) are high enough to make this approach seldom useful. I have only decompiled to debug problems with closed-source vendors' products (deadlocks in DB abstraction layer, ugh).
Bytecode was actually obfuscated, I think, but we nonetheless found the underlying problem -- it was an actual design problem.
I guess it really comes down to what your Java code is for, how it's distributed and who your clients are. We don't obfuscate anything, as we've never found one that was particularly good and it tends to be more trouble than it's worth. If someone has access to our JAR files and has the knowledge to be able to sniff around inside them, then there's far more worrying things that they can do than rip off our source code.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I'm trying the retrieve the last modified file name with a matching pattern starts with Order_ and there should not be any hidden files, however it throws compilation error.
try {
File dir = new File("< dir >");
if (!dir.isDirectory()) {
Optional<File> op = Arrays.stream(dir.listFiles(File::isFile))
.max((f1, f2) -> Long.compare(f1.lastModified(), f12lastModified()))
.filter(fl -> fl.getName().startsWith("Order_") && !fl.getCanonicalPath().endsWith("~"))
; // Unhandled exception compilation error for canonicalPath method
}
} catch (Exception e) {
}
Exception: Unhandled exception: java.io.IOException
Any ideas would be greatly appreciated.
This feels like lambda abuse (using a hammer to butter your toast instead of, you know, a butter knife, because you just bought it and it's all shiny and new).
.max() returns either 1, or 0, elements, in the form of an Optional. you then filter that optional to check if the naming is right.
In other words, if the most recently modified file so happens to not start with Order_, this all returns Optional.NONE which surely wasn't your intent. You want to flip your max and your filter line.
More generally, you don't want to do this with lambdas. Inline Lambdas are the lesser evil - they are not exception transparent, not mutable local variable transparent, and not control flow transparent.
These 3 properties are fantastic when a lambda represents code that will run in some other context (e.g. another thread or much later). They are downsides when the code is going to be run then and there.
That means that when a lambda-based strategy and a non-lambda-based strategy for an inline code concept are roughly equally good, then you should prefer the non-lambda-based strategy. This becomes particularly poignant here, as the code is using obsolete API (the old java.io.File API, instead of the newer java.nio.file API).
In this case, .getCanonicalPath() is slightly odd behaviour: The only functional difference between invoking fl.getName().endsWith(...) and fl.getCanonicalPath().endsWith(...) is that the latter will first follow the link if the referenced 'file' is a soft-link.
That sounds like soft-links matter, and if they matter, you don't want this API as it is wonky and ill defined in the face of soft-links. The new API deals with it better, you'd want to use that (java.nio.file.Files's walk method, for example). If soft linking doesn't matter, then it's easy: Replace .getCanonicalPath() with .getName() and all is well. Well, after you fix your bug and flip the filter and max lines back in their right positions.
Note also that .getCanonicalPath() is slow - it needs to hit the disk, or at least, it might. (It will if it is a soft-link; the API doesn't define whether it will in other cases. The JVM impl is free to hit disk on some OSes and not on others. It may run blazingly fast on your system and run dog slow on another, making it hard to test).
I am a .NET and JavaScript developer. Now I am working in Java, too.
In .NET LINQ and JavaScript arrow functions we have =>.
I know Java lambdas are not the same, but they are very similar. Are there any reasons (technical or non technical) that made java choose -> instead of =>?
On September 8, 2011, Brian Goetz of Oracle announced to the OpenJDK mailing list that the syntax for lambdas in Java had been mostly decided, but some of the "fine points" like which type of arrow to use were still up in the air:
This just in: the EG has (mostly) made a decision on syntax.
After considering a number of alternatives, we decided to essentially
adopt the C# syntax. We may still deliberate further on the fine points
(e.g., thin arrow vs fat arrow, special nilary form, etc), and have not
yet come to a decision on method reference syntax.
On September 27, 2011, Brian posted another update, announcing that the -> arrow would be used, in preference to C#'s (and the Java prototype's) usage of =>:
Update on syntax: the EG has chosen to stick with the -> form of the
arrow that the prototype currently uses, rather than adopt the =>.
He goes on to provide some description of the rationale considered by the committee:
You could think of this in two ways (I'm sure I'll hear both):
This is much better, as it avoids some really bad interactions with existing operators, such as:
x => x.age <= 0; // duelling arrows
or
Predicate p = x => x.size == 0; // duelling equals
What a bunch of idiots we are, in that we claimed the goal of doing what other languages did, and then made gratuitous changes "just for the sake of doing something different".
Obviously we don't think we're idiots, but everyone can have an opinion :)
In the end, this was viewed as a small tweak to avoid some undesirable
interactions, while preserving the overall goal of "mostly looks like
what lambdas look like in other similar languages."
Howard Lovatt replied in approval of the decision to prefer ->, writing that he "ha[s] had trouble reading Scala code". Paul Benedict of Apache concurred:
I am glad too. Being consistent with other languages is a laudable goal, but
since programming languages aren't identical, the needs for Java can lead to
a different conclusion. The fat arrow syntax does look odd; I admit it. So
in terms of vanity, I am glad to see that punted. The equals character is
just too strongly associated with assignment and equality.
Paigan Jadoth chimed in, too:
I find the "->" much better than "=>". If arrowlings at all instead of the
more regular "#(){...}" pattern, then something definitely distinct from the
gte/lte tokens is clearly better. And "because the others do that" has never
been a good argument, anyway :D.
In summary, then, after considering arguments on both sides, the committee felt that consistency with other languages (=> is used in Scala and C#) was less compelling than clear differentiation from the equality operators, which made -> win out.
But Lieven Lemiengre was skeptical:
Other languages (such as Scala or Groovy) don't have this problem because
they support some placeholder syntax.
In reality you don't write "x => x.age <= 0;"
But this is very common "someList.partition(x => x.age <= 18)" and I agree
this looks bad. Other languages make this clearer using placeholder syntax
"someList.partition(_.age <= 18)" or "someList.partition(it.age <= 18)"
I hope you are considering something like this, these little closures will
be used a lot!
(And I don't think replacing '=>' with '->' will help a lot)
Other than Lieven, I didn't see anyone who criticized the choice of -> and defended => replying on that mailing list. Of course, as Brian predicted, there were almost certainly opinions on both sides, but ultimately, a choice just has to be made in these types of matters, and the committee made the one they did for the stated reasons.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Contextualisation
Im am implementing a bytecode instrumenter using the soot framework in a testing context and I want to know which design is better.
I am building the TraceMethod object for every Method in a Class that I am instrumenting and I want to run this instrumenter on multiple Classes.
Which Option offers more performance(Space–time)?
Option 1: (Maps)
public class TraceMethod {
boolean[] decisionNodeList;
boolean[] targetList;
Map<Integer,List<Integer>> dependenciesMap;
Map<Integer,List<Double>> decisionNodeBranchDistance;
}
Option 2: (Objects)
public class TraceMethod {
ArrayList<Target> targets = new ArrayList<Target>();
ArrayList<DecisionNode> decisionNodes = new ArrayList<DecisionNode>();
}
public class DecisionNode {
int id;
Double branchDistance;
boolean reached;
}
public class Target {
int id;
boolean reached;
List<DecisionNode> dependencies;
}
I have implemented the option 2 by myself, but my boss suggest me the option 1 and he argue that is "lighter". I saw that in this article "Class Object vs Hashmap" that HashMaps use more memory than Objects, but im still not convinced that my solution(option 2) is better.
Its a simple detail but i want to be sure that I am using the optimal solution, my concern is about performance(Space–time). I know that the second option are way better in term of maintainability but i can sacrifice that if its not optimal.
In general you should always go for maintenance, and not for supposed performance. There are few good reasons for this:
We tend to be fascinated by speed difference between array vs HashMap, but in real enterprise application these differences are not big enough to account in visible difference in application speed.
Most common bottlenecks in application are in either database or network.
JVM optimizes code to some extent
It is very unlikely that your application will have performance issues due to maintainable code. More likely case is your boss will run out of money when you will have millions lines of unmaintainable code .
Approach 1 has the potentical to be much faster and uses less space.
Especially for a byte code instrumenter, I would first implement approach 1.
And then when it works, replace both Lists with non generic lists that use primitive types instead of the Integer and Double object.
Note that an int needs 4 bytes while an Integer (Object) need 16 - 20 bytes, depending on the machine (16 at PC, 20 at android).
The List can be replaced with GrowingIntArray (I have found that in an statistic package of Apache if I remeber correctly) which uses primitive ints. (Or maybe just replaced by an int[] once you know that the content cannot change anymore)
Then you just write your own GrowingDoubleArray (or use double[])
Remember Collections are handy but slower.
Objects use 4 times more space than primitives.
A byte code instrumenter needs performance, it is not a software that is run once a week.
Finally I would not replace that Maps with non generic ones, that seems
for me to much work. But you may try it as last step.
As a final optimization step: look how many elements are in your lists or maps. If that are usually less than 16 (you have to try that out), you may switch to a linear search,
which is the fastest, for a very low number of elements.
You even can make your code intelligent to switch the search algorithms once the number of elements exceed a specific number.
(Sun/Oracle java does this, and Apple/ios, to) in some of their Collections.
However this last step will make you code much more complex.
Space as an exmample:
DecisionNode: 16 for the class + 4 (id) + 20 (Double) +4 (boolean) = 44 + 4 padding to then next multiple of 8 = 48 bytes.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I need suggestion for the right approach to apply conditions in Java.
I have 100 conditions based on which I have to change value of a String variable that would be displayed to the user.
an example condition: a<5 && (b>0 && c>8) && d>9 || x!=4
More conditions are there but variables are the same more or less.
I am doing this right now:
if(condition1)
else if(condition2)
else if(condition3)
...
A switch case alternative would obviously be there nested within if-else's i.e.
if(condition1)
switch(x)
{
case y:
blah-blah
}
else if(condition2)
switch(x)
{
case y:
blah-blah
}
else if(condition3)
...
But I am looking for some more elegant solution like using an Interface for this with polymorphic support , What could be the thing that I could possibly do to avoid lines of code or what should be the right approach.
---Edit---
I actualy require this on an android device. But its more of a java construct here.
This is a small snapshot of conditions that I have with me. More will be added if a few pass/fail. That obviously would require more if-else's with/without nesting. In that case would the processing go slow.
I am as of now storing the messages in a separate class with various string variables those I have kept static so if a condition gets true
then I pick the static variable from the only class and display that
one. Would that be right about storing the resultant messages.
Depending on the number of conditional inputs, you might be able to use a look-up table, or even a HashMap, by encoding all inputs or even some relatively simple complex conditions in a single value:
int key = 0;
key |= a?(1):0;
key |= b?(1<<1):0;
key |= (c.size() > 1)?(1<<2):0;
...
String result = table[key]; // Or result = map.get(key);
This paradigm has the added advantage of constant time (O(1)) complexity, which may be important in some occasions. Depending on the complexity of the conditions, you might even have fewer branches in the code-path on average, as opposed to full-blown if-then-else spaghetti code, which might lead to performance improvements.
We might be able to help you more if you added more context to your question. Where are the condition inputs coming from? What are they like?
And the more important question: What is the actual problem that you are trying to solve?
There are a lot of possibilities to this. Without knowing much about your domain, I would create something like (you can think of better names :P)
public interface UserFriendlyMessageBuilder {
boolean meetCondition(FooObjectWithArguments args);
String transform(String rawMessage);
}
In this way, you can create a Set of UserFriendlyMessageBuilder and just iterate through them for the first that meets the condition to transform your raw message.
public class MessageProcessor {
private final Set<UserFriendlyMessageBuilder> messageBuilders;
public MessageProcessor(Set<UserFriendlyMessageBuilder> messageBuilders) {
this.messageBuilders = messageBuilders;
}
public String get(FooWithArguments args, String rawMsg) {
for (UserFriendlyMessageBuilder msgBuilder : messageBuilders) {
if (msgBuilder.meetCondition(args)) {
return msgBuilder.transform(rawMsg);
}
}
return rawMsg;
}
}
What it seems to me is "You have given very less importance to design the product in modules"
Which is the main factor of using OOP Language.
eg:If you have 100 conditions and you are able to make 4 modules then therotically for anything to choose you need 26 conditions.
This is an additional possibility that may be worth considering.
Take each comparison, and calculate its truth, then look the resulting boolean[] up in a truth table. There is a lot of existing work on simplifying truth tables that you could apply. I have a truth table simplification applet I wrote many years ago. You may find its source code useful.
The cost of this is doing all the comparisons, or at least the ones that are needed to evaluate the expression using the simplified truth table. The advantage is an organized system for managing a complicated combination of conditions.
Even if you do not use a truth table directly in the code, consider writing and simplifyin one as a way of organizing your code.
I could actually see a use for the Google Annotations Gallery in real code:
Stumble across code that somehow works
beyond all reason? Life's short. Mark
it with #Magic and move on:
#Magic
public static int negate(int n) {
return new Byte((byte) 0xFF).hashCode()
/ (int) (short) '\uFFFF' * ~0
* Character.digit ('0', 0) * n
* (Integer.MAX_VALUE * 2 + 1)
/ (Byte.MIN_VALUE >> 7) * (~1 | 1);
}
This is a serious question. Could this be used in an actual code review?
Quite. Well, not all of them, but many could be substitutes for longer comments.
That holds true for not too many of these annotations, but some (as in your example) could be handy.
It may be said that these annotations present the most common comments in a shorter and perhaps more readable way.
You can later process them, and add tresholds for, say, the number of #Magic annotations. If a project becomes too "magic", measures should be taken.
It would be easier to use comments with a key such as "MAGIC", then work with those. Hudson and Eclipse and other tools can count or mark those occurrences.
I can definitely see how the #CarbonFootprint would fit into several client's CSR policies, and the #WTF("comment") annotation would be really handy when you're working on a new project where you're not sure whether a certain piece of code actually is needed to work around some crazy bug/corner-condition or if it's just random, left-over crap that no one knew how to write better at the time.
FYI, Sonar seems to now include a better revision plugin.
Anyway, were you not to guess, i think the short project name is clear enough about this project's intentions : gag the annotations for what they can become when left free : an equivalent to the oh-so-y2k XML hell.
I guess some people may have missed the acronym and the date of the that Google Annotation Gallery (GAG) on April 1st... or maybe in some countries it's not a national day for jokes, or gags...