What's the package of a Java array class? - jvm

This question is for JVM specification advocates. According to the JVMS, Java SE 7 edition, section 5.3.3, last paragraph:
If the component type is a reference type, the accessibility of the array class is determined by the accessibility of its component type. Otherwise, the accessibility of the array class is public.
Thus an array class can have package visibility. Logically I would expect that, if foo.baz.MyClass has package visibility, then an array of MyClass is visible only to package foo.baz. But I can't find anything in the specification supporting this view. Section 5.3 says that the run-time package, that should be used to determine visibility constraints, is built of the binary name of the package plus the defining classloader. But the binary name comes from the classfile, and array classes do not have classfiles. Similar issue for the primitive classes (e.g., Boolean.TYPE), which apparently have public visibility, but I cannot find information about them anywhere.
Can you spot a point in the JVMS where the package of array/primitive classes is clearly defined (or a reason why there is none)?

Isn't that exactly what the quote from the specification is saying?
If the component type is a reference type, the accessibility of the array class is determined by the accessibility of its component type.
If you have a class some.pkg.SomeClass and want to use it as some.pkg.SomeClass[] the accessibility is determined by the accessibility of its component type. In this case the component type is some.pkg.SomeClass.
The other case is for native types, and you can't add more native types to Java.

Related

Why there is no SelectorT?

I am trying to implement a custom control (I call it DataGrid) , which I choose to derive from Selector. In cppwinrt , I write some like this
struct DataGrid : SelectorT<DataGrid>
{
}
This code does not compile. In fact , there is no such a struct called SelectorT in any of the shipped Windows.UI.Xaml.Controls.Primitives.h files. I've checked the winmd file shipped with the SDK (19041) , found that Selector is Composable (has the ComposableAttribute attribute), so, SelectorT should have been generated , what I've missed ? Many thanks!
There is no SelectorT because Selector can not be subclassed. The TypenameT class templates in the consuming projection are not provided for convenience, they exist to provide user-defined subclasses of Xaml types that support it. This allows the user to define their own implementations of overrideable methods. (Think of it as similar to C++ virtual functions, but in a complicated COM aggregation way)
The docs don't appear to spell out in clear words which classes can be subclassed, and which ones can't. You can deduce this, though, from the presence of ComposableAttribute on the type, as in FrameworkElement.

May a ref class be stored by value in a managed class?

Say I have a managed type Foo:
ref class Foo
{};
And a managed type Bar:
ref class Bar
{
Foo foo;
};
Note that Bar does not contain a Foo^, but a Foo.
Assume that Bar is gcnew'd.
Is this permitted?
It compiles without warning, yet the documentation says:
Reference (ref) types can only be instantiated on the managed heap, not on the stack or on the native heap. Value types can be instantiated on the stack or the managed heap.
I suppose it's transitively "on the managed heap", but I'd like confirmation.
Reason I ask is that I'm possibly seeing some evidence that my foo is corrupt when I later access it; MCVE perhaps to follow in a subsequent question, depending on the outcome of this one!
It seems to be valid.
The language is specified by ECMA-372, which does not appear to prevent this (though I cannot immediately find any explicitly stated semantics for it, either).
In particular, §23 (p141) lists restrictions on "mixed types":
This clause is reserved for possible future use.
A mixed type is a native class, ref class, or native array that requires object members, either by declaration or by inheritance, to be allocated on both the CLI heap and some other part of memory.
Examples of mixed types are:
A native class containing a member whose type is a non-simple value type, a ref class type, or interface class type.
A native array of elements whose type is a value type other than a fundamental type, or a ref class type.
A ref class or value class containing a member whose type is a native class or native array.
A program that defines or declares a mixed type is ill-formed.
…and your example is not one of them. I'd expect to find it listed there if it were prohibited.
(not sure what's going on with that first paragraph)

How can deserialization of polymorphic trait objects be added in Rust if at all?

I'm trying to solve the problem of serializing and deserializing Box<SomeTrait>. I know that in the case of a closed type hierarchy, the recommended way is to use an enum and there are no issues with their serialization, but in my case using enums is an inappropriate solution.
At first I tried to use Serde as it is the de-facto Rust serialization mechanism. Serde is capable of serializing Box<X> but not in the case when X is a trait. The Serialize trait can’t be implemented for trait objects because it has generic methods. This particular issue can be solved by using erased-serde so serialization of Box<SomeTrait> can work.
The main problem is deserialization. To deserialize polymorphic type you need to have some type marker in serialized data. This marker should be deserialized first and after that used to dynamically get the function that will return Box<SomeTrait>.
std::any::TypeId could be used as a marker type, but the main problem is how to dynamically get the deserialization function. I do not consider the option of registering a function for each polymorphic type that should be called manually during application initialization.
I know two possible ways to do it:
Languages that have runtime reflection like C# can use it to get
deserialization method.
In C++, the cereal library uses magic of static objects to register deserializer in a static map at the library initialization time.
But neither of these options is available in Rust. How can deserialization of polymorphic objects be added in Rust if at all?
This has been implemented by dtolnay.
The concept is quite clever ans is explained in the README:
How does it work?
We use the inventory crate to produce a registry of impls of your trait, which is built on the ctor crate to hook up initialization functions that insert into the registry. The first Box<dyn Trait> deserialization will perform the work of iterating the registry and building a map of tags to deserialization functions. Subsequent deserializations find the right deserialization function in that map. The erased-serde crate is also involved, to do this all in a way that does not break object safety.
To summarize, every implementation of the trait declared as [de]serializable is registered at compile-time, and this is resolved at runtime in case of [de]serialization of a trait object.
All your libraries could provide a registration routine, guarded by std::sync::Once, that register some identifier into a common static mut, but obviously your program must call them all.
I've no idea if TypeId yields consistent values across recompiles with different dependencies.
A library to do this should be possible. To create such a library, we would create a bidirectional mapping from TypeId to type name before using the library, and then use that for serialization/deserialization with a type marker. It would be possible to have a function for registering types that are not owned by your package, and to provide a macro annotation that automatically does this for types declared in your package.
If there's a way to access a type ID in a macro, that would be a good way to instrument the mapping between TypeId and type name at compile time rather than runtime.

Can't create private classes with same name in different modules

Official docs on visibility modifiers in Kotlin say that package-level elements marked private are be visible only in the module in which they are declared.
So class A declared in Module1.kt isn't visible in Module2.kt. But if I try to add to Module2.kt it's own class A I get the Redeclaration: A error.
Since I can't access in Module2.kt to Module1's A class, why isn't the name A free to use?
"A module is a set of Kotlin files compiled together" (Visibility Modifiers - Kotlin Programming Language).
In your example, Module1.kt and Module2.kt are separate source files and despite their names they are not necessarily part of separate modules:
If they are compiled together then they are part of the same module.
If they are compiled separately from one another then they will be part of different modules and each can define their own private class A.
Keep in mind that visibility is different from identity. Even if a class is not visible elsewhere it doesn't mean that it does not exist. Loading multiple class declarations with the same fully-qualified name can (and likely will) cause issues at run-time.

How jvm classloader loads class that is defined inside another class?

How does JVM loads class that are defined inside another class?
Example: Lets say, there is a class B that is defined inside class A
package test.sample;
Class A {
// some instructions
Class B {
// few more instructions
}
}
In this case,
How does classloader load the class B? (i.e., How does it identify class B?)
What will be the fully qualified name of class B?
Inner classes are a Java language feature, not a JVM feature. That is, Java compilers "flatten" the class structure, so the JVM just sees regular classes, usually with $ in their names. In this case, there would be classes test.sample.A and test.sample.A$B (the latter being the fully qualified name of B). Anonymous inner classes get compiler-defined names, typically starting at 1 and counting up: test.sample.A$6, for example. The compiler may add methods with names like access$200 to allow the enclosing class and inner class to access each others' private members. (Note that $ is legal, though discouraged, in user-defined class and method names, so the presence of a $ in a name does not mean it is compiler-generated; for that, there's the Synthetic attribute and ACC_SYNTHETIC modifier bit, exposed reflectively via methods like Class.isSynthetic().)
The JVM loads these classes just like any other class, typically looking for a file test/sample/A$B.class in some JAR file, but also possibly loading them across a network, generating them on-the-fly with a bytecode manipulation library, etc.
When generating class files that reference an inner class (defining, containing, or simply using), Java compilers emit InnerClasses attributes specifying the containment relationships, for the aid of separate compilation and reflection (Class.getDeclaringClass() and Class.getEnclosingClass()). Class files for classes defined inside a method also contain an EnclosingMethod attribute referring to the enclosing method, for reflection (Class.getEnclosingMethod() and Class.getEnclosingConstructor()). However, these attributes are only checked for syntactic well-formedness by the JVM during loading and linking; inconsistencies are not reported until the reflective methods are actually called.