Comments (11)
Modified the code to access relevant annotations.
import ballerina/io;
type AnnotRecord record {|
string value;
|};
type AnnotRecord1 record {|
typedesc value;
|};
annotation AnnotRecord annot on type;
annotation AnnotRecord1 annot1 on service, type;
@annot {
value: "T1"
}
public type Service service object {
resource function get pet() returns string ;
};
listener Listener lst = new Listener(9090);
@annot1 {
value: Service
}
service Service on lst {
resource function get pet() returns string {
return "string";
}
}
public class Listener {
int port;
Service? s = ();
public function 'start() returns error? {
Service s = <Service> self.s;
AnnotRecord1? annot = (typeof s).@annot1;
io:println("start: ", annot);
if annot is AnnotRecord1 {
io:println(Service.@annot);
io:println(annot.value.@annot);
}
}
public function gracefulStop() returns error? {
}
public function immediateStop() returns error? {
}
public function detach(Service s) returns error? {
}
public function attach(Service s, string[]? name = ()) returns error? {
self.s = s;
AnnotRecord1? annot = (typeof s).@annot1;
io:println("attach: ", annot);
if annot is AnnotRecord1 {
io:println(Service.@annot);
io:println(annot.value.@annot);
}
}
public function init(int port) {
self.port = port;
}
}
Running executable
attach: {"value":typedesc Service}
start: {"value":typedesc Service}
{"value":"T1"}
{"value":"T1"}
The annotation is available at start
. Assuming this translates to native code also, is accessing annotations at start
an option for now, @TharmiganK?
from ballerina-lang.
This issue occurs when a service calls the listener from the compiler before setting the annotations to the types. (We are not generating type descriptors for the service types. Therefore, we need to retain the annotations in the type for now). With the following example, we can generate the issue.
import ballerina/io;
type AnnotRecord record {|
string value;
|};
type AnnotRecord1 record {|
typedesc value;
|};
annotation AnnotRecord annot on type;
annotation AnnotRecord1 annot1 on service, type;
@annot {
value: "T1"
}
public type Service service object {
resource function get pet() returns string ;
};
listener Listener lst = new Listener(9090);
@annot1 {
value: Service
}
service Service on lst {
resource function get pet() returns string {
return "string";
}
}
public class Listener {
int port;
public function 'start() returns error? {
}
public function gracefulStop() returns error? {
}
public function immediateStop() returns error? {
}
public function detach(service object {} s) returns error? {
}
public function attach(service object {} s, string[]? name = ()) returns error? {
AnnotRecord1? annot = (typeof s).@annot1;
io:println(annot);
if annot is AnnotRecord1 {
io:println((typeof Service).@annot1);
io:println((typeof (annot.value)).@annot);
}
}
public function init(int port) {
self.port = port;
}
}
from ballerina-lang.
Is this a duplicate of #33594 then? Are they accessible in the start method?
We tried fixing the original issue back then, but deferred due to complexity of a workaround vs going with the typedesc change.
from ballerina-lang.
The annotation is available at
start
. Assuming this translates to native code also, is accessing annotations atstart
an option for now?
Will check on this
from ballerina-lang.
Is this a duplicate of #33594 then? Are they accessible in the start method?
We tried fixing the original issue back then, but deferred due to complexity of a workaround vs going with the typedesc change.
Yes.
from ballerina-lang.
@MaryamZi I moved the logic to start
and the service level annotations are now present for the service types defined in the same package (if I defined the service type in a different package and import, the annotations are present in attach
and start
)
But the original issue is still there where I cannot get the resource level annotations. The following is a reduced ballerina code which represents my actual use case:
import ballerina/io;
type ResourceAnnotation record {
string value;
};
type ParameterAnnotation record {
string value;
};
type ServiceAnnotation record {
string value?;
typedesc<ServiceContract> serviceContractType?;
};
annotation ResourceAnnotation ResourceConfig on function;
annotation ParameterAnnotation ParamConfig on parameter;
annotation ServiceAnnotation ServiceConfig on service, type;
public type Service service object {
};
public type ServiceContract service object {
*Service;
};
public type User record {|
int id;
string name;
string email;
|};
@ServiceConfig {
value: "users-service-contract"
}
public type UsersService service object {
*ServiceContract;
@ResourceConfig {value: "get-users"}
resource function post users(@ParamConfig {value: "payload-param"} User user) returns User|error;
};
public class Listener {
Service? s = ();
public function 'start() returns error? {
ServiceAnnotation? serviceConfig = (typeof self.s).@ServiceConfig;
io:println("self-start: ", serviceConfig);
if serviceConfig is ServiceAnnotation {
io:println("self-start: ", UsersService.@ServiceConfig);
typedesc<ServiceContract>? serviceContractType = serviceConfig.serviceContractType;
io:println("self-start: ", serviceContractType);
if serviceContractType is typedesc<ServiceContract> {
io:println("self-start: ", serviceContractType.@ServiceConfig);
}
}
// Need to access the resource level and resource parameter level annotations here
}
public function gracefulStop() returns error? {
}
public function immediateStop() returns error? {
}
public function detach(Service s) returns error? {
}
public function attach(Service s, string[]? name = ()) returns error? {
self.s = s;
ServiceAnnotation? serviceConfig = (typeof s).@ServiceConfig;
io:println("self-attach: ", serviceConfig);
if serviceConfig is ServiceAnnotation {
io:println("self-attach: ", UsersService.@ServiceConfig);
typedesc<ServiceContract>? serviceContractType = serviceConfig.serviceContractType;
io:println("self-attach: ", serviceContractType);
if serviceContractType is typedesc<ServiceContract> {
io:println("self-attach: ", serviceContractType.@ServiceConfig);
}
}
}
public function init(int port) {
}
}
@ServiceConfig {
serviceContractType: UsersService
}
service UsersService on new Listener(8080) {
resource function post users(User user) returns User|error {
return user;
}
}
Note: Please note the resource level and resource parameter level annotations in the service contract type -
UsersService
from ballerina-lang.
This is a bug in the compiler. The issue is that we added those annotations to the annotation map, but at runtime, we didn't apply these annotations to the type associated with the resource functions and parameters. We only set the annotations which attached to the service type. (As a solution, we need to add those annotations to their respective types by calling the processAnnotation
function.) @MaryamZi
from ballerina-lang.
Seems to be an issue at runtime rather.
The check at https://github.com/ballerina-platform/ballerina-lang/blob/v2201.9.2/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/AnnotationUtils.java#L61 is no longer sufficient with type reference types.
from ballerina-lang.
Let's use
from ballerina-lang.
Let's use
- Annotation doesn't get populated before listener init #33594 to track the original issue and
- Method annotations not available on object type descriptors #43122 to track the new issue (tagging this for U10)
Closing this since this was/is tracked in other issues.
from ballerina-lang.
This issue is NOT closed with a proper Reason/ label. Make sure to add proper reason label before closing. Please add or leave a comment with the proper reason label now.
- Reason/EngineeringMistake - The issue occurred due to a mistake made in the past.
- Reason/Regression - The issue has introduced a regression.
- Reason/MultipleComponentInteraction - Issue occured due to interactions in multiple components.
- Reason/Complex - Issue occurred due to complex scenario.
- Reason/Invalid - Issue is invalid.
- Reason/Other - None of the above cases.
from ballerina-lang.
Related Issues (20)
- [Bug]: An invalid `change return type` code action is provided for the cache `get` operation
- [Bug]: The formatter produces incorrect indentation for a query collect within a function expression body
- [Bug]: Compiler crash with nested query expression containing another non nested field
- [Task]: Fix failing unit tests for Java 21 migration
- A new list isn't created for function calls with rest arguments with lists
- [Bug]: Enable temporary disabled github workflow-only failing `QueryExprWithQueryConstructTypeTest.testNegativeScenarios`
- [Task]: Release a docker debug image for each Ballerina release
- [Bug]: Error occurs when using observability tracing with wso2.controlplane module HOT 5
- [Improvement]: Directly resolve semtypes from AST, instead via BTypes
- [Improvement]: Refactor `BUnionType`'s `getMemberTypes()` usages
- [Bug]: Ballerina Notebook not working with 2201.10.0 HOT 2
- [Task]: Investigate into the ballerina library level 5 failure for PR #43303 HOT 3
- [Task]: Fix failing langlib tests for Java 21 migration
- [Task]: Refactor ballerina integration tests
- [Task]: Fix failing integration tests for Java 21 migration
- [Task]: Implement Java 21 Virtual threads based Runtime Concurrency model
- [Improvement]: Properly distinguish between type descriptor and type in runtime HOT 1
- [Bug]: Getting `missing single backtick token` warning for the doc comment containing backticks
- Lang artifacts are not publishing to the local Maven repository in PR builds HOT 1
- [Bug]: Getting NPE when accessing a field with a default value which is generated from rest binding with the optional field HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ballerina-lang.