I am using the AWTUtilities class in my application to create custom window shapes. As far as I know, there is no other way to do it. It is a requirement.
The javadoc generation gives me this error:
warning: com.sun.awt.AWTUtilities is Sun proprietary API and may be removed in a future release
What exactly does this mean? I can use it, but it may stop working with any release? Why put it in, then? More importantly, and the real question here, if Sun takes it out, will they likely replace it with another way to do the same thing? Is that what the warning is for?
I suppose I could just check for the presence of the AWTUtilities class before calling the code. But that's just obnoxious if I don't need to do it.
Does anyone have any experience with similar classes? Were they eventually accepted into the API and the warning removed or replaced with another method of doing the same thing? Do I need to be concerned about this?
FYI, I have read this:
How to distribute AWTUtilities
The Oracle documentation states:
Note: the com.sun.awt.AWTUtilities class is not part of an officially supported API and appears as an implementation detail. The API is only meant for limited use outside of the core platform. It may change drastically between update releases, and it may even be removed or be moved in some other packages or classes. The class should be used via Java Reflection. Supported and public API will appear in the next major JDK release.
JDK 7 has been a long time coming so it could be awhile. Whether you should use it is a risk management question that only your company can answer. If we are talking about an internal application where the deployed JRE can be guaranteed then you are not going to have a problem because you can guarantee a compatible JRE. If we are talking about deploying to external customers then you need to have a support plan if this provisional API ever changes.
A stable way to do this would be to create a Shell in SWT as per this snippet and then use the SWT_AWT bridge to get a Frame to use in your application:
java.awt.Frame frame = SWT_AWT.new_Frame(shell);
If you are just deploying to a single platform (like Windows) then tossing a single SWT jar plus the native library. If you are targeting multiple platforms then this becomes a pain.
So those are the two choice: deal with the AWTUtilities risk or use the SWT_AWT bridge.
EDIT:
Some time has passed and Java 7 is out. There is documentation on the officially supported way to accomplish this in the Java Tutorials. The section "How to Implement a Shaped Window" at the bottom gives an example. This of course assumes you can mandate Java 7
You don't need a new Frame object, you can only use
this.setShape(shape);
or your frame name like this
Frame1.setShape(shape);
a lot of AWT methods has been applied to java.awt.Frame
Related
I don't know how to fix this error can you please help me?
Execution failed for task ':app:processDebugMainManifest'.
Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not "opens java.io" to unnamed module #203e7cb0
I am very grateful for every answer.
Explanation: Your tooling (The code that powers the processDebugMainManifest task, which I think is the Android Build System) is trying to do a task in java, but this task is simply not available in public APIs. Instead of accepting that it is impossible to write an Android Build system in java in the way the android team wanted, the devs of android instead realised that JVMs can do it, it's just that there is no public accesspoint to ask it to do it. Thus, they decided to use the not-intended-for-public-consumption part, given that without doing this they can't do the job at all, and have accepted the maintenance burden.
Unfortunately, Team OpenJDK is aggressively locking this stuff down, even though usually there is no ready alternative (as in, the right order is obviously to first make an inventory of commonly used private APIs, then make suitable alternatives for the top 95% of usage, and then proceed with lockdown, though not in such a heavyhanded fashion as they have chosen to do - team OpenJDK hasn't done this)1.
That's what this warning means: The java release you use is no longer 'allowing' it. This java release has broken processDebugMainManifest for a dubious reason. Likely whatever pDMM is trying to do is now completely impossible in java releases that locked this down and thus...
Solution:
Downgrade your java.
Download AdoptOpenJDK's OpenJDK8 which is free and open source.
In particular when doing android dev this is generally a good idea. Android has never worked well with newer javas; neither the features introduced in the language, nor the additions to the core libs (as android has its own implementation of them). The existence of this courtcase probably isn't helping things along.
[1] I have oversimplified a tad; for example, there are a few methods in sun.misc.Unsafe which OpenJDK openly states are sometimes neccessary and they are more or less committed to keeping Unsafe available until they've found adequate alternatives for all such uses (if only they had that attitude for a few more commonly used internal bits, there wouldn't be such a gulf between the community and the openjdk team). Also, there is common 'internal API' usage which is indeed inappropriate, such as the widespread use of sun.misc.BASE64Encoder which no library/tool/app ever should have used, and for which alternatives have always been available, and these days, alternatives are baked into the JDK itself: Team OpenJDK's decision to effectively eliminate both direct access to BASE64Encoder as well as shutting down all attempts to work around the lack of direct access are therefore probably justified. It's shades of gray: Whenever private API use occurs, part of the blame lies with the OpenJDK for not having an alternative, and part of the blame lies with the library/tool/app for envisioning the way it works in a way that can't be done (easily) without relying on internals that weren't designed for public use like this. My impression is that the core OpenJDK contributors are wildly misjudging themselves on this divide and basically placing virtually all blame not on them but on the library builders, and aren't giving sensible solutions other than 'pull your entire tool/library/app from existence, you should never have written it'. Thus, I'm faring on statistics here, but it is quite likely the explanation of whatever's going on here: The OpenJDK is locking down the ability to do this stuff without having a reasonable alternative, therefore processDebugMainManifest, even the most recent version, would still cause this error and they can't fix this error without rewriting a ton of code and completely changing how it works for the users of the Android Build infrastructure.
Some insights (including that vibe that OpenJDK core contributors seem to feel the blame lies almost entirely with apps/libraries/tools) is on display on this Inside Java podcast with Alan Bateman.
In Android world, there are two popular injection/hijack/hooking frameworks :
Xposed and Android Substrate
The Xposed's mechanism is described in a development tutorial.
The author of Android Substrate compared the two frameworks in FAQ and here, but he didn't say how it works.
I just wonder:
How does Android Substrate work?
Jay Freeman(Saurik) in this post(http://www.cydiasubstrate.com/id/34058d37-3198-414f-a696-73e97e0a80db/) talks about the deference in xposed and substrate and also talks about how they deffer in the way they work its a great read.
Although the similarities are vast between the two frameworks, the actual implementation of hooking processes etc differs enough for you to be able to have both frameworks running side by side.
However, the biggest benefits that I can see for Substrate over XPosed, is the fact that XPosed removes the Java Security Model, while Substrate preserves it, as well as having the ability to wait for a class to be loaded before hooking a method as described in the following quote from #xmllmx answer regarding "Orthogonality";
To make this easier, Xposed provides a set of helpers for common use cases: you can hook when the VM starts, when Zygote takes control, when a particular package is loaded, or when a command line application is executed. You need to know which of these to use, and it is still unclear how you'd hook a class loaded via a dyamic runtime-created class loader (such as against downloaded code).
Substrate instead does away with all of this, thanks to MS.hookClassLoad, an API it provides that allows you to wait for particular classes to be loaded from any class loader at any time. This allows you to write hooks in a way that is less brittle to changes, less prone to simple mistakes, and less limited by how the developer of the target application decided to load their program's code.
In conclusion, in my opinion anyway, both frameworks a very similar and both viable options in achieving the same goal. The only major weighing fact which separates them is the timescales between when each was released. Where XPosed has been around for much longer and has been tried and tested and put through it's paces over the interim between the release of XPosed an the release of Cydia Substrate for Android, which Jay Freeman (Saurik) openly acknowledges
Regardless of this, Cydia Substrate is a powerful and extremely viable alternative to XPosed. Furthermore, you don't have to only limit yourself to developing for one of these frameworks, because (as mentioned previously) both frameworks can be installed on your device without conflict, so developing for both or simply trying it, will in no way hinder you from using your currently install XPosed Modules, Packages or Extensions.
I recently read the blog posts on Pushing Pixels that describe how to achieve native transparency and translucency with pure Java. The needed classes reside on com.sun.awt namely com.sun.awt.AWTUtilities.
I was wondering how i could include the needed classes (not just this one) into my distro since the classes are available only when you have a jdk installed and you start the jvm through there. So the users of my program will not have the needed classes to run my program.
Any ideas?
AWTUtilities, as the package implies is an implementation package and is subject to change. I don't think it is a good idea to distribute the class from both technical and legal viewpoints.
Technically, com.sun.awt.AWTUtlities is bound to have possibly unknown dependencies on other classes and internal implementation details, specific to Java 6 u10 and above (the release in which it appeared). This unknown dependency angle is bound to hold water, since painting and graphics will require changes in some of the native implementations as well.
Secondly, this is bound to change in Java 7, since the only release Sun hasn't made a release of java.awt.AWTUtilities with support for transparency, is because they do not make changes to public APIs except in major releases.
IANAL, but I do not think it is wise to engage in the act of redistributing software without having run past a lawyer. Besides, customers do not like the idea of having an unsupported deployment of any software in their systems.
Update
All Sun JREs (not just JDKs) from 6u10 onwards come with com.sun.awt.AWTUtilities, so the simplest course of action would be to get your users to have Java 6u10 or later on their systems, and for your application to handle any resulting exception gracefully.
I'm trying to code an application which runs un different java platforms like J2SE, J2ME, Android, etc. I already know that I'll have to rewrite most of the UI for each platform, but want to reuse the core logic.
Keeping this core portable involves three drawbacks that I know of:
Keeping to the old Java 1.4 syntax, not using any of the nice language features of Java 5.0
only using external libraries that are known to work on those platforms (that is: don't use JNI and don't have dependencies to other libs which violate this rules)
only using the classes which are present on all those platforms
I know of ways to overcome (1): code in 5.0 style and automatically convert it to 1.4 (retroweaver - haven't tried it yet, but seems ok).
I think (2) is a problem that I just have to accept.
Now I'd like to know what's the best workarround for (3), especially collection classes, which I miss the most. I can think of those:
Most programmers I know just don't use Set, Map, List, etc. and fallback to Vector and plain Arrays. I think this makes code ugly in the first place. But I also know that the right choice between TreeSet/Hashset or LinkedList/ArrayList is crucial for performance, and always using Vector and Arrays can't be right.
I could code my own implementations of that classes. This seems to be reinventing the wheel, and I think I could not do it as good as others have done.
Since Java is open source, I could grab the sourcecode of the J2SE Collections framework and include into my application when building for J2ME. I don't know if this is a good idea, though. Pherhaps there are good reasons not to do this.
Maybe there already are libraries out there, which rebuild the most important features of the collections framework, but are optimized for low end systems, pherhaps by not implementing functionality that is used infrequently. Do you know any?
Thanks for your answers and opinions!
Edit: I finally found a (complex, but nice) solution, and I thought by providing my own answer and accepting it, the solution would become visible at the top. But to the contrary, my answer is still at the very bottom.
J2ME is brutal, and you're just going to have to resign yourself to doing without some of the niceties of other platforms. Get used to Hashtable and Vector, and writing your own wrappers on top of those. Also, don't make the mistake of assuming that J2ME is standard either, as each manufacturer's JVM can do things in profoundly different ways. I wouldn't worry much about performance initially, as just getting correctness on J2ME is enough of a challenge. It is possible to write an app that runs across J2ME, J2SE and Android, as I've done it, but it takes a lot of work. One suggestion that I'd have is that you write the core of your application logic and keep it strictly to java.lang, java.util and java.io. Anywhere where you're going to be doing something that might interact with the platform, such as the file system or network, you can create an interface that your core application code interacts with, that you have different implementations for the different environments. For example, you can have an interface that wraps up HTTP stuff, and uses javax.microedition.io.HttpConnection with J2ME and java.net.HttpURLConnection on Android. It's a pain, but if you want to maintain an app running on all three of those environments, it can get you there. Good luck.
It's been a while since I asked this question, and I while since I found a nice, working solution for the problem, but I had since forgotton to tell you.
My main focus was the Java Collections Framework, which is part of the java.util package.
I've finally taken the source code of Suns Java 6.0 and copied all the classes that belong to the Collections framework into a project of my own. This was a Java 6.0 project, but I used the jars from J2ME as classpath. Most of those classes that I copied depend on other J2SE classes, so there are broken dependencies. Anyway, it was quite easy to cut those depensencies by leaving out everything that deals with serialization (which is not a priority for me) and some minor adjustments.
I compiled the whole thing with a Java 6 compiler, and retrotranslator was used to port the resulting bytecode back to Java 1.2.
Next problem is the package name, because you can't deliver classes from java.util with a J2ME application and load them - the bootstrap class loader won't look into the applications jar file, the other bootloaders aren't allowed to load something with that package name, and on J2ME you can't define custom classloaders. Retrotranslator not only converts bytecode, it also helps to change name references in existing bytecode. I had to move and rename all classes in my project, e.g. java.util.TreeMap became my.company.backport.java.util.TreeMap_.
I was than able to write actual J2ME application in a second Java 6.0 project which referenced the usual java.util.TreeMap, using the generic syntax to create type-safe collections, compile that app to Java 6.0 byte code, and run it through retrotranslator to create Java 1.2 code that now references my.company.backport.java.util.TreeMap_. Note that TreeMap is just an example, it actually works for the whole collections framework and even for 3rd party J2SE Jars that reference that framework.
The resulting app can be packaged as a jar and jad file, and runs fine on both J2ME emulators and actual devices (tested on a Sony Ericsson W880i).
The whole process seems rather complex, but since I used Ant for build automation, and I needed retranslator anyway, there only was a one-time overhead to setup the collection framework backport.
As stated above, I've done this nearly a year ago, and writing this mostly from the top of my head, so I hope there are no errors in it. If you are interested in more details, leave me a comment. I've got a few pages of German documentation about that process, which I could provide if there is any demand.
We faced exactly this situation in developing zxing. If J2ME is in your list of targets, this is your limiting factor by far. We targeted MIDP 2.0 / CLDC 1.1. If you have a similar requirement, you need to stick to Java 1.2. Java 1.4 language features are definitely not present (like assert) and in general you won't find anything after 1.2 in J2ME.
We did not use external libraries, but, you could package them into your deployed .jar file with little trouble. It would make the resulting .jar bigger, and that could be an issue. (Then you can try optimizers/shrinkers like ProGuard to mitigate that.)
I did end up reimplementing something like Collections.sort() and Comparator since we needed them and they are not in J2ME. So yeah you might consider doing this in cases, though only where necessary.
We used Vector and Hashtable and arrays since there is no other choice, really, in J2ME. I would just use them unless you have a reason not to, and that would be performance I guess. In theory JVM makers are already optimizing their implementation but that doesn't mean you couldn't make a better one... I guess I would be surprised if it is worth it in the vast majority of cases. Just make sure you really need to do this before putting in the effort.
To answer part of your question another collections library would be Javolution which can be built for j2me.
In IE, I can use the classid "clsid:CAFEEFAC-0015-0000-0011-ABCDEFFEDCBA" to tell it to use java version 1.5.0_11. Is there an equivalent for Firefox and other browsers?
I can use the classid "clsid:CAFEEFAC-0015-0000-0011-ABCDEFFEDCBA" to tell it to use java version 1.5.0_11
Not any more, you can't, for good (security) reasons. See http://java.sun.com/javase/6/webnotes/deploy/deployment-policy.html
There is an IE-only clsid mechanism for asking for "5.0_(something)" in general - http://java.sun.com/javase/6/webnotes/family-clsid.html . This was introduced in 5.0u7 so if you have any one JRE from u7 onwards installed you get this behaviour, otherwise you get the old and incompatible behaviour.
Sun did not deign to provide a similar mechanism for other browsers until 6.0u10, when they added a bunch more mechanisms for choosing versions and deprecated all the old ones including the 5.0u7 family chooser. See https://jdk6.dev.java.net/plugin2/version-selection/ for all the gory details.
So what behaviour you get depends not only on the browser and whether the version of the JVM you want is installed, but what other versions are installed as well. The new behaviour is at least consistent, but it is completely different to all that went before and not entirely compatible. By the time your apps' deployment HTML has been updated to cope with it, they'll probably work with 1.6 anyway.
So in summary, as usual with applets, the whole thing's a bloody mess. Yay.