Error while executing below code,
Caused by: java.lang.IllegalAccessError: tried to access class
com.google.common.collect.AbstractTable from class
ImmutableTable.copyOf(listItemsToProcess.parallelStream()
.map(item ->
ProcessorInstanceProvider.getInstance()
.buildImmutableTable(item))
.collect(() -> HashBasedTable.create(),
HashBasedTable::putAll,
HashBasedTable<Integer, String,
Boolean>::putAll)
);
Error in coming on - HashBasedTable::putAll Using Oracle's 1.8 jre
This is a compiler bug, related reports are
JDK-8152643: “Javac compiles method reference that allows results in an IllegalAccessError”
JDK-8059632: “Method reference compilation uses incorrect qualifying type”
Note that the first report has the status “Fixed in 8u102”, so downloading JDK8u102 could solve the issue. Of course, when using a compiler other than javac, e.g. ECJ, you have to ensure that that compiler is up to date as well.
In either case, you have to recompile the source code, as it is a compiler issue. But then, the compiled code should even work with older JREs.
To explain the issue, normally, invocations should be encoded into the byte code using the compile-time type of the receiver (or the explicit type in case of static methods), regardless of the declaring type of the actual method implementation. So if you have a public class A inheriting the public method foo from the non-public class B, an invocation of A.foo should be encoded as A.foo rather than B.foo. For ordinary invocations, the compilers work that way, but for method references, javac (and afaik also older versions of ECJ) failed to do that correctly. So when encountering a class trying to access B.foo directly without having access to B, an IllegalAccessError is thrown.
It works when using a lambda expression instead, as then, the invocation is compiled into an ordinary invocation instruction, for which the compiler works correctly, within a synthetic method and a reference to that synthetic method is used when constructing an instance of the functional interface at runtime. Since the synthetic method recides within the same class, it’s always accessible.
AbstractTable was introduced in Guava version 15. Take a look at your classpath configuration; you're probably using an earlier library version at runtime.
Interesting, i replaced method references with Lambda expression and it worked.
ImmutableTable.copyOf(itemList.parallelStream()
.map(item ->
ProcessorInstanceProvider.get()
.buildImmutableTable(item))
.collect(() -> HashBasedTable.create(),
(a, b) -> a.putAll(b),
(a, b) -> a.putAll(b))
);
Related
In object-oriented languages like C++ you don't have to call the base constructor. I don't understand why I need to do it in a psuedo object-oriented language like javascript. My base constructor has virtual elements that need to be setup before I call it. Constructors worked fine in ES5, why ruin them with this restriction. This error is garbage, it should be removed.
In C++ the compiler creates code to call the base constructor for you before your derived class constructor is called. Your C++ derived class definition can specify which base constructor to call and what to pass it (if there is a choice).
That's how the C++ specification is written. See short explanation here.
Javascript ES6 classes do not work the exact same way. You have to insert a place in your code where the base constructor is called with super(...) and you can specify or compute the parameters to pass to the base constructor.
In both C++ and Javascript, you can't access your own instance methods or properties before the base constructor has been called.
FYI, Java is even more restrictive than Javascript. You must put a call to super() or this() as the first statement of your constructor. Javascript at least lets you put logic that doesn't use this before calling the constructor.
In your Javascript, you can't stop this error without rewriting your code to work a different way. It's not an error you can disable.
There are valid OOP reasons (whether you agree with them or not) to not allow references to an object until all base classes have been fully initialized. Or, you can go back to the pre-ES6 way of initializing objects where there are no controls on how you do things and you can do whatever you want.
If you show us your code and explain what you're trying to do, we can likely suggest a different design that solves your problem and does not have this issue.
I'm experimenting with Swift frameworks. I've discovered some strange behavior. Look at the following enumeration from my framework:
public enum Sobchak {
case Walter(String.Index)
}
In my framework, this compiles without a problem. Unit tests using it work fine. But if I create another project, reference my framework, and then create a declaration using the enumeration above, the compiler actually crashes with a segmentation fault. (It also kills SourceKitService completely.) The problem appears to be related to String.Index (which is actually a struct, not a type alias). If I take it out, everything works. If I use a simple type like Int or String, no problem. I can even use type aliases, e.g.:
public enum Sobchack {
case Walter(Array<Int>.Element)
}
This compiles just fine. (Of course, anyone saying Array<Int>.Element instead of just Int should be quietly shown the door.)
Anyone have any insight on this? String.Index is definitely the culprit. I can't reproduce this problem with any other type.
Is it possible to get an instance of java.lang.reflect.Method by using the new method reference feature of Java 8?
That way I would have a compile time check and refactoring would be also easier. Also, I wouldn't need to catch the exceptions (which shouldn't been thrown after all).
Short answer: No.
You will get a lambda of that method, not a java.lang.reflect.Method. You do not know the name of the method. Just as you can not have a reference to a "property" of a java bean.
You can have a reference to the getter or setter but that is also a lambda and you do not know the actual name.
In any case you'd have to provide the name as a String and that can't be checked by the compiler. I also tried this but failed. It simply can't be done unless you write something that checks the javacode/bytecode. But there are tools that do that.
Maybe the Criteria API could be used for that, but it depends on the requirements.
http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html
There you'd have a SingularAttribute or similar field on a "metamodel" and then the regular java compiler can check the (generic) type of it.
I am consuming a predefined wsdl with svcutil a la:
svcutil some_service.wsdl
one of the methods generated has the following signature:
[System.ServiceModel.OperationContractAttribute(Action="http://ws.example.org/SubmitData", ReplyAction="*")]
SubmitDataResponse SubmitData( SubmitDataRequest request )
While scvutil from VS2010/.net35 generates only the above and VS has no problem lanuching the service,
the svcutil program that is part of VS2012/.net45 also generates a method with the signature
[System.ServiceModel.OperationContractAttribute(Action="http://ws.example.org/SubmitData", ReplyAction="*")]
Task<SubmitDataResponse> SubmitDataAsync( SubmitDataRequest request );
This causes a run-time exception:
System.InvalidOperationException: Cannot have two operations in the
same contract with the same name, methods SubmitDataAsync and
SubmitData in type MyType violate this rule. You can change the name
of one of the operations by changing the method name or by using the
Name property of OperationContractAttribute.
I can work around this by deleting the Async appended methods or simply using svcutil from VS2010. But I am wondering why svcutil generates an interface that causes a runtime exception (is this a bug?), and whether there is something additional I am supposed to do to make it work.
The default behaviour appears to have been changed. If you provide the /syncOnly parameter it preserved the old behaviour for me.
/syncOnly - Generate only synchronous method
signature. Default: generate synchronous
and task-based asynchronous method
signatures.
is there a list of de-facto immutable classes in the jdk?
technically Immutable classes include the obvious Integer, Double etc..
de-facto immutable will include for example java.lang.String - it might technically be mutable but de-facto it is not.
Also, are there Interfaces/Abstract classes which are required (as stated in the javadoc) to be immutable?
if you cannot provide a complete List, i would already be happy if you know a bunch of classes which state immutability in its javadoc..
I try to compile the list as much as I can:
java.lang.String
The wrapper classes for the primitive types:
java.lang.Integer
java.lang.Byte
java.lang.Character
java.lang.Short
java.lang.Boolean
java.lang.Long
java.lang.Double
java.lang.Float
java.lang.StackTraceElement (used in building exception stacktraces)
Most of the enum classes
java.math.BigInteger
java.math.BigDecimal
java.io.File
java.awt.Font
java.awt.BasicStroke
java.awt.Color
java.awt.GradientPaint,
java.awt.LinearGradientPaint
java.awt.RadialGradientPaint,
java.awt.Cursor
java.util.Locale
java.util.UUID
java.util.Collections
java.net.URL
java.net.URI
java.net.Inet4Address
java.net.Inet6Address
java.net.InetSocketAddress
most subclasses of java.security.Permission
You can use MutabilityDetector and feed it JARs from the JDK to enumerate most immutable classes. It's "most" because it's so strict that even the tiny bit of state change in java.lang.String is enough to make it considered mutable, but the goal is to account for this by 1.0 release.
You can download the latest JAR here: https://github.com/MutabilityDetector/MutabilityDetector/releases
Here's an example of it's use. This is what I used to get most of the immutable JDK 1.7 classes on OSX:
java -jar MutabilityDetector-0.9.5.jar -r IMMUTABLE -cp /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre/lib/rt.jar
Here's the output (slightly cleaned up):
https://gist.github.com/CalebFenton/85fc87edf64033afe110
I needed to do this for Android framework classes. The tricky part was finding a JAR with Android classes, and not just stubs which is the one included in the SDK. The good people at Robolectric make one, which you can download here: http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22android-all%22
You can see the list of immutable Android classes I use, which includes many JDK classes here:
https://github.com/CalebFenton/simplify/blob/master/smalivm/src/main/resources/immutable_classes.cfg
Classes whose object contents cannot be modified is called immutable classes. All primitive data types(Wrapper classes only) are immutable. For any class to be immutable the following needs to be done.
Make all fields private
Don't provide mutators
Ensure that methods can't be overridden by either making the class
final (Strong Immutability) or making your methods final (Weak
Immutability)
If a field isn't primitive or immutable, make a deep clone on the way
in and the way out.
Thank you