I'm using GWT.
When it is compiling the Java code to Javascript code, sometimes it changes some of the members' names.
for example:
private int height;
becomes in the JS:
height_0;
Example:
public class TestClass
{
private int a;
public TestClass()
{
a = 0;
}
public TestClass(int a)
{
this.a = a;
}
public int getMember()
{
return a;
}
public void advance()
{
a++;
}
}
Will result in output like so:
function TestClass_0(){
this.a_0 = 0;
}
function TestClass_1(a){
this.a_0 = a;
}
function TestClass(){
}
_ = TestClass_1.prototype = TestClass_0.prototype = TestClass.prototype = new Object_0;
_.advance_0 = function advance(){
++this.a_0;
}
;
_.getClass$ = function getClass_1(){
return Lcom_autodesk_autocadws_gwt_platform_testExporter_TestClass_2_classLit;
}
;
_.getMember_0 = function getMember(){
return this.a_0;
}
;
_.a_0 = 0;
}
The name of the member a was changed to a_0. In some cases, when using web workers, the code will be compiled differently on the web worker script, and the member's name will not be changed (or will be cjanged to a_1, for example).
My problem with that is when I transfer objects in messages to web workers. When coding the web worker side in Java, I'm expecting to access the member a, and not a_0. Using getters does not solve the issue, since they are simply replaced with direct access when compiled to JS.
My question:
Why are these naming changes occur? In which cases? Is it possible to avoid them?
Thanks a lot.
In most cases, the fields will actually be renamed to something lik a, b, etc. What you're seeing here is due to compiling with -style PRETTY which does not obfuscate the code.
The reason GWT obfuscates the code is to make it smaller.
If you need to pass objects to the outside world, you have to serialize them (or map them to JavaScript objects) to a stable structure.
The easiest way to do it is to use a JavaScriptObject. You can also have a look at gwt-exporter.
Related
I've managed to get COM4J to use some functionality in the windows IMAPI (CD writing).
However I've failed to get any of the calls that return SAFEARRAYs working, but this project doesn't appear to be currently active ...
The DLL is usually in C:\Windows\System32\imapi2.dll, and using it also requires using C:\Windows\System32\imapi2fs.dll
Looking around for a JAVA-COM bridge project that is active led me to JNA.
The remit of the project to simplify JAVA-COM bridging intrigued me .... however I fell at the first hurdle, and am hoping someone can help.
So far I've taken the Microsoft IMAPI examples and written a Powershell application, from which I have the series of calls I need to make to the API.[CDInterface][1]
The first thing you need to do with IMAPI is create an Instance of IDiskMaster2, so I've declared that via an Imapi2 interface, like so
public interface Imapi2 extends Library {
Imapi2 INSTANCE = (Imapi2)
Native.load("C:/Windows/System32/imapi2.dll" , Imapi2.class);
public static class IDiscMaster2 extends Structure {
int getCount;
public int getCount() {
return getCount;
}
}
IDiscMaster2 createMsftDiscMaster2();
}
Then in the main code
Imapi2.IDiscMaster2 recorderList = Imapi2.INSTANCE.createMsftDiscMaster2();
System.out.println("Found " + recorderList.getCount() + " Recorders");
Just putting 'imapi2' in the call to Native.load() didn't work either.
I'm guessing I'm doing something fundamentally wrong, but it's not clear how you get JNA to 'see' a new dll you want to interface to ..... and also I am kind of afraid there is something very different about this API from the othe APIs that people are using JNA to talk to, so may not be worth trying!
public interface Imapi2 extends Library {
Imapi2 INSTANCE = (Imapi2)
Native.load("C:/Windows/System32/imapi2.dll" , Imapi2.class);
public class IDiscMaster2 extends Dispatch {
public static final CLSID CLSID_MsftDiscMaster2 = new CLSID("2735412F-7F64-5B0F-8F00-5D77AFBE261E");
public IDiscMaster2() {
}
private IDiscMaster2(Pointer pvInstance) {
super(pvInstance);
}
public static IDiscMaster2 create() {
PointerByReference pbr = new PointerByReference();
WinNT.HRESULT hres = Ole32.INSTANCE.CoCreateInstance(CLSID_MsftDiscMaster2, null, WTypes.CLSCTX_ALL, null, pbr);
if (COMUtils.FAILED(hres)) {
System.out.println("ERROR: Failed to create instance");
return null;
}
return new IDiscMaster2(pbr.getValue());
}
public WinNT.HRESULT _getCount(Pointer count ){
return (WinNT.HRESULT) _invokeNativeObject(2, new Object[]{count}, WinNT.HRESULT.class);
}
public long getCount() {
try {
long count = -1;
Pointer ptr = new Pointer(count);
WinNT.HRESULT result = _getCount(ptr);
COMUtils.checkRC(result);
return count;
} catch ( Exception e ) {
System.out.println("Error : " + e.getMessage());
}
return -1;
}
}
Then invocation in main changed to
Imapi2 imapi2Lib = Imapi2.INSTANCE;
Imapi2.IDiscMaster2 recorderList = new Imapi2.IDiscMaster2();
System.out.println("Found " + recorderList.getCount() + " Recorders");
IntelliJ shows up uninvoked methods, so it doesn't look like create() is getting called. Not sure if this is because I need to call it, or down to the function implementing IDispatch not IUnknown.
[1]: https://github.com/nosdod/CDInterface
I've answered this in a similar question which I originally marked this as a duplicate of. However, given the difficulty loading this, your case is unique enough that I'll attempt to give a separate answer.
The general case for COM is that there is an API function that creates the object. You have mapped this as createMsftDiscMaster2(). Note that you have allocated a resource here and it needs to be disposed of when you are done with it; the API documentation should tell you how to do that (possibly by calling Release() from IUnknown.)
Your next step is to map the IDiscMaster2 COM class. I see two mappings here, so I'm confused as to which one you want. The one at the top of your question is incorrect, but the one extending Dispatch later is the correct way to start, but I'm not clear where you've gone after that. The rest of the class should look similar to the internals of the Dispatch class in JNA.
In that class you can see the boilerplate that you will follow. Note that it extends Unknown which follows the same boilerplate for offsets 0, 1, and 2 for the first 3 COM functions QueryInterface, AddRef, and Release. Dispatch picks up with offsets 3, 4, 5, and 6 for COM functions GetTypeInfoCount, GetTypeInfo, GetIDsOfNames, and Invoke.
So in your mapping for DiskMaster2 you will pick up with offset 7, and your mapping will look like:
public HRESULT TheFunctionName(FOO foo, BAR bar) {
return (HRESULT) this._invokeNativeObject(7,
new Object[] { this.getPointer(), foo, bar },
HRESULT.class);
}
This is where you need to locate the actual header file for this class to determine the order in which the functions appear in the Vtbl. It looks like you attempted to do this with your code, but the offset 2 is already assigned in Unknown, the lowest one you'll be able to use is 7 (and continue on with 8, 9, 10 for each function in this COM interface, in the correct order -- which you must determine from the Vtbl.)
Based on this header, you can see those functions mapped in order and your offsets should be: 7: get__NewEnum, 8: get_Item, 9: get_Count, and 10: get_IsSupportedEnvironment. Use those header function mappings as a start and change them to the _invokeNativeObject() format above. (They all return HRESULT, you'll just be changing the argument list.)
I'm trying to learn Java Lamdas.
I'm trying to convert the following code into lambda representation but it's not working:
private void foo(Data data) {
Observable.just(data).subscribeWith(new DisposableObserver<Data>() {
int count = 0;
int pageCount = 0;
#Override
public void onNext(Data data) {
Timber.e("onNext()");
count = data.getCount();
pageCount = data.getPage();
}
#Override
public void onError(Throwable e) {
e.printStackTrace();
}
#Override
public void onComplete() {
Log.e("class", "onComplete");
abc(count, pageCount);
}
});
}
private void bar(Data data) {
Observable.just(data).subscribeWith({
int count = 0;
int pageCount = 0;
data -> {
Timber.e("onNext()");
count = data.getCount();
pageCount = data.getPage();
},
e -> e.printStackTrace(),
() -> {
Log.e("class", "onComplete");
abc(count, pageCount);
}
});
}
This is giving me error. I'm not really sure how to fix it.
You missed one essential part. You can't just turn any anonymous inner class instantiation into a lambda.
Quoting from here:
The major benefit of java 8 functional interfaces is that we can use lambda expressions to instantiate them and avoid using bulky anonymous class implementation.
The core property of a functional interface: it has one single abstract method.
More details can be found here for example.
Beyond that, I think the real answer is on a meta level: you have to understand what you are doing. Meaning: you don't use this or that concept because you heard about it, and someone said: "that is great". You use it because it makes sense in your context.
And of course, you can only decide whether something is useful, "the right thing" ... when you understand that concept. In other words: the real answer is to step back (for now); and study the concept of lambdas first. And to then decide where using it will give benefits to your code base.
Finally: as expressed by user Holger in the comments - there is another no-go in that inner class; as it contains fields; which are even "shared" by some of the methods; another aspect that prevents transforming this class into a single pure lambda.
I'm trying to automate the testing process for customly written programs designed to solve competitive programming challenges. Below is a dummy sample implementation of Solution:
public class Solution {
private static String dummyField = "initial";
public static int initialize(InputStream in) {
//competitive programmer custom code
System.out.println(dummyField);
dummyField = "changed";
return subCaseCount;
}
public void processSingleSubCase(InputStream in) {
//competitive programmer custom code
}
}
Prewritten test code for solution regardless of its implementation:
public void testSolution() throws FileNotFoundException {
for(File testResource : testResources) {
InputStream in = new FileInputStream(testResource);
int subCaseCount = Foo.initialize(in);
for (int subCase = 0; subCase < subCaseCount; subCase++) {
new Foo().processSingleSubCase(in);
}
//magic call to re-init all static fields without knowing their number/names in advance goes here
}
//console current output:
//initial
//changed
//changed
//...
//desired:
//initial
//initial
//initial
//....
}
The static fields can be mutable, so caching the initial values and mapping them to field names using reflection as a first setup, then reassigning them in between iterations won't do.
I did manage to come up with a working solution which basically reloads the class using a different class loader in between iterations, it did work but was slow: it took about 50 seconds just to reload classes 300 times (test resources are auto generated and I'd like to have the flexibility to auto generate as many as tolerable).
Is there a faster alternative?
My two thoughts for how to do this are:
Use instances rather than statics, since that way the new instance for each test is fresh.
If you need (or want) to stick with statics: Prior to the first test, cache the static values, then reassign them from the cache between tests. If the static values are object references referring to mutable objects, you'll need to make deep copies.
The answer to this question seems obvious, but I need to be completely sure. So if answer can provide authoritative reference with clear non-ambiguous statements, that would be great.
Say I have the following two methods
public CollectionResponse<Dog> getDogs(Identification request){
MemcacheService syncCacheDog = MemcacheServiceFactory.getMemcacheService();
syncCacheDog.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO));
// ........
value = (byte[]) syncCacheDog.get(key); // read from cache
if (value == null) {
// get value from other source
// ........
syncCacheDog.put(key, value); // populate cache
}
// ........
}
public CollectionResponse<Cat> getCats(Identification request){
MemcacheService syncCacheCat = MemcacheServiceFactory.getMemcacheService();
syncCacheCat.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO));
// ........
value = (byte[]) syncCacheCat.get(key); // read from cache
if (value == null) {
// get value from other source
// ........
syncCacheCat.put(key, value); // populate cache
}
// ........
}
Are syncCacheDog and syncCacheCat pointing to the same map? Or if I want them to be pointing to the same map, do I have to create
static MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
and then use syncCache inside both methods?
On the other hand, if it is a singleton, how do I maintain two different caches? I.e. can someone please copy and paste one of my methods and show it written with a namespace and instead of dealing with generic byte to deal with a specific object such as Dog?
Yes, from my experience with GAE and its documentation, Memcache service is a singleton. Even more, different versions of the application all see the same cache.
In order to maintain different caches do the usual: use a prefix. Maintaining a unique set of prefixes for different classes should be relatively easy - have an enum somewhere, keeping track of the maximum prefix. And never reuse the old prefix numbers.
public enum MemcachePrefix {
DOGS(1),
CATS(2);
// Max: 2.
public final int value;
private MemcachePrefix (int value) {this.value = value;}
};
public class Dog {
static final MemcachePrefix MEMCACHE_PREFIX = MemcachePrefix.DOGS;
};
class Main {
public static void main (String[] args) {
Dog dog = new Dog();
System.out.println (dog.MEMCACHE_PREFIX);
}
}
There is also Namespaces. Instead of manually adding the prefix to the cache key you can use it as a namespace, letting GAE do the key manipulations for you.
What's the best practice for specifying flags in a Java method?
I've seen SWT using int as bitfields, like:
(example partially from "Effective Java, 2nd Ed." page 159):
public class Text {
public static final int STYLE_BOLD = 1 << 0; // 1
public static final int STYLE_ITALIC = 1 << 1; // 2
void printText(String text, int flags) {
}
}
and your client call looks like:
printText("hello", Text.STYLE_BOLD | Text.STYLE_ITALIC);
..but this is discouraged as you can mixed flags (int values) from different classes together without any compiler checks.
In the same book ("Effective Java"), I see the use of EnumSet, but then your user call becomes:
printText("hello", EnumSet.of(Style.Bold, Style.ITALIC));
I find this a bit verbose and I prefer the elegance of SWT.
Is there any other alternative or is this basically the two tastes you must pick?
Guess you have hit a wall. I don't see any other option. Java is verbose that's a fact. In situations like this i usually add a local variable to make the code more readable. You can do this,
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.ITALIC);
printText("hello", styles);
If you want bit style flags, Java wraps them in a BitSet. It's been around for ages, yet few people bother to use it (preferring embedding C style bit handling in ints).
The api for BitSet can be found here.
Coupled with a few well chosen static ints, it does pretty well until you start getting into checking and setting multiple bits in one pass.
I advise that you go with the EnumSet approach.
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.Italic);
This approach provides better type safety, and Style being an enum will have full-blown OO capabilities.
Late answer for anyone coming across this. Here is one way to do it to reduce memory and have a nice enum like api:
public static class MyFlag {
public static final MyFlag A = new MyFlag(1<<0);
public static final MyFlag B = new MyFlag(1<<1);
public static final MyFlag C = new MyFlag(1<<2);
public static final MyFlag ALL = A.and(B).and(C);
private final int flag;
private MyFlag(int flag){
this.flag = flag;
}
public MyFlag and(MyFlag limit){
return new MyFlag(flag & limit.flag);
}
public MyFlag not(MyFlag limit){
return new MyFlag(flag | ~limit.flag);
}
public boolean isSet(MyFlag limit){
if(limit ==null){
return false;
}
return (this.flag & limit.flag) != 0;
}
}
method:
public void doFoo(MyFlag flag){
if(MyFlag.A.isSet(flag)){
....
}
if(MyFlag.C.isSet(flag)){
....
}
}
call:
x.doFoo(MyFlag.A.and(MyFlag.C));
If you only have a limited number of methods that will be taking a set of styles (like printText, in your example), you can tweak their signature to take a variable number of Style params:
void printText(String text, Style... flags) {
EnumSet<Style> style = logicalOr(flags); // see comment below
...
}
And then your calls are very close to the untyped (int) flag route:
printText("hello", Style.BOLD, Style.ITALIC);
Sadly, there is no EnumSet.of(E... ) factory, just EnumSet.of(E first, E... more), so you'll need a generic logicalOr method to split your array into first + rest chunks. Left as an exercise to the reader =).