I am learning how to write Minecraft mods (version 1.14.4) and was able to make an item. Now I am trying to make a block. I am following this tutorial video which actually covers 1.14.3, but I thought it would be close enough.
I am currently getting this error:
[20Mar2020 14:09:10.522] [Server thread/INFO] [net.minecraftforge.registries.ForgeRegistry/REGISTRIES]: Registry Block: Found a missing id from the world examplemod:examplemod
[20Mar2020 14:09:10.613] [Server thread/ERROR] [net.minecraftforge.registries.GameData/REGISTRIES]: Unidentified mapping from registry minecraft:block
examplemod:examplemod: 676
I also get presented with this at runtime:
I have tried messing around with how i'm naming the registries but I just can't seem to pin down what the issue is. Maybe i'm not formatting my json files correctly?
Note that ItemList and BlockList are just classes that contain static instances of each Block/Item I have created.
ExampleMod.java:
// The value here should match an entry in the META-INF/mods.toml file
#Mod(ExampleMod.MOD_ID)
public class ExampleMod
{
// Directly reference a log4j logger.
private static final Logger LOGGER = LogManager.getLogger();
public static final String MOD_ID = "examplemod";
public ExampleMod() {
// Register the setup method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
// Register the enqueueIMC method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC);
// Register the processIMC method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);
// Register the doClientStuff method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff);
// Register ourselves for server and other game events we are interested in
MinecraftForge.EVENT_BUS.register(this);
}
private void setup(final FMLCommonSetupEvent event)
{
// some preinit code
LOGGER.info("HELLO FROM PREINIT");
LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName());
}
private void doClientStuff(final FMLClientSetupEvent event) {
// do something that can only be done on the client
LOGGER.info("Got game settings {}", event.getMinecraftSupplier().get().gameSettings);
}
private void enqueueIMC(final InterModEnqueueEvent event)
{
// some example code to dispatch IMC to another mod
InterModComms.sendTo(ExampleMod.MOD_ID, "helloworld", () -> { LOGGER.info("Hello world from the MDK"); return "Hello world";});
}
private void processIMC(final InterModProcessEvent event)
{
// some example code to receive and process InterModComms from other mods
LOGGER.info("Got IMC {}", event.getIMCStream().
map(m->m.getMessageSupplier().get()).
collect(Collectors.toList()));
}
// You can use SubscribeEvent and let the Event Bus discover methods to call
#SubscribeEvent
public void onServerStarting(FMLServerStartingEvent event) {
// do something when the server starts
LOGGER.info("HELLO from server starting");
}
// You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD
// Event bus for receiving Registry Events)
#Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public static class RegistryEvents {
#SubscribeEvent
public static void onItemsRegistry(final RegistryEvent.Register<Item> blockItemEvent)
{
ItemList.bomb_item = new Item(new Item.Properties().group(ItemGroup.COMBAT));
ItemList.bomb_item.setRegistryName(new ResourceLocation(ExampleMod.MOD_ID, "bomb_item"));
ItemList.mystery_block = new BlockItem(BlockList.mystery_block, new Item.Properties().group(ItemGroup.MISC));
ItemList.mystery_block.setRegistryName(new ResourceLocation(ExampleMod.MOD_ID, "mystery_block"));
blockItemEvent.getRegistry().registerAll(ItemList.bomb_item, ItemList.mystery_block);
LOGGER.info("Items registered.");
}
#SubscribeEvent
public static void onBlocksRegistry(final RegistryEvent.Register<Block> blockRegistryEvent) {
BlockList.mystery_block = new Block(Block.Properties.create(Material.CAKE)
.hardnessAndResistance(2.0f, 2.0f)
.sound(SoundType.GLASS));
BlockList.mystery_block.setRegistryName(new ResourceLocation(MOD_ID, "mystery_block"));
blockRegistryEvent.getRegistry().registerAll(BlockList.mystery_block);
LOGGER.info("Blocks registered.");
}
}
}
blockstates/mystery_block.json:
{
"variants": {
"": {
"model": "examplemod:block/mystery_block"
}
}
}
models/block/mystery_block.json:
{
"parent": "block/cube_all",
"textures": {
"all": "examplemod:block/mystery_block"
}
}
models/item/mystery_block.json:
{
"parent": "examplemod:block/mystery_block"
}
All that means is that at some point you had a block registered as "examplemod:examplemod", and now you don't. You can safely ignore the message. If you start a new world instead of opening an old one, you won't get that message.
As an aside, HarryTalks is not a recommended way to learn to mod (on the Minecraft Forge forums ). Apparently he uses several bad practices (I have not actually used them).
Alternative suggestions are Cadiboo's example mod, or McJty's tutorials.
Related
I'm currently working on my discord bot. One problem I encountered is that I'm not able to find out how to allow the bot to wait for a user reply after a message is sent.
I also have tried reading the git documentation regarding using RestAction over here: https://github.com/DV8FromTheWorld/JDA/wiki/7)-Using-RestAction but it seems it does not mention anything about implementing an "await" function similar to discord.js
I tried coding to mimic such an effect:
public class EventHandler extends ListenerAdapter {
private static final String PREFIX = "&";
public static String[] args;
public void sendMessage(String s, GuildMessageReceivedEvent event) {
event
.getChannel()
.sendMessage(s)
.queue();
}
public void onGuildMessageReceived (GuildMessageReceivedEvent event) {
args = event
.getMessage()
.getContentRaw()
.split(" ");
if (args[0].equalsIgnoreCase(PREFIX + "any_command")) {
sendMessage("Type hello!");
if (args[0].equalsIgnoreCase(PREFIX + "hello") {
sendMessage("hello there!");
}
}
}
}
Main class:
import net.dv8tion.jda.core.AccountType;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.JDABuilder;
public class Main {
public static void main(String[] args) throws Exception {
JDA jda = new JDABuilder(AccountType.BOT)
.setToken("token goes here")
.setAutoReconnect(true).build();
try {
jda.addEventListener(new EventHandler());
} catch (Exception e) {
e.printStackTrace();
}
}
}
This doesn't register the hello command typed after the prompt given. My best guess would be that the condition is never met since the original condition overrides the upcoming one (args[0] is already any_command)
Any help would be appreciated!
I'd suggest the EventWaiter from JDA-Utilities (https://github.com/JDA-Applications/JDA-Utilities/)
Taking a quick look at the source, looks like you'll need something like this
EventWaiter waiter = new EventWaiter();
// SO wouldn't let me insert new lines for some reason.
waiter.waitForEvent(GuildMessageReceivedEvent.class, (event) -> event.getMessage().getContentRaw().equalsIgnoreCase("hello"), (event) -> event.getChannel().sendMessage("hello!").queue()));
I have an app. I have a big button that allows the user to sync all their data at once to the cloud. A re-sync feature that allows them to send all their data again. (300+ entries)
I am using RXjava2 and retrofit2. I have my unit test working with a single call. However I need to make N network calls.
What I want to avoid is having the observable call the next item in a queue. I am at the point where I need to implement my runnable. I have seen a bit about Maps but I have not seen anyone use it as a queue. Also I want to avoid having one item fail and it report back as ALL items fail, like the Zip feature would do. Should I just do the nasty manager class that keeps track of a queue? Or is there a cleaner way to send several hundred items?
NOTE: SOLUTION CANNOT DEPEND ON JAVA8 / LAMBDAS. That has proved to be way more work than is justified.
Note all items are the same object.
#Test
public void test_Upload() {
TestSubscriber<Record> testSubscriber = new TestSubscriber<>();
ClientSecureDataToolKit clientSecureDataToolKit = ClientSecureDataToolKit.getClientSecureDataKit();
clientSecureDataToolKit.putUserDataToSDK(mPayloadSecureDataToolKit).subscribe(testSubscriber);
testSubscriber.awaitTerminalEvent();
testSubscriber.assertNoErrors();
testSubscriber.assertValueCount(1);
testSubscriber.assertCompleted();
}
My helper to gather and send all my items
public class SecureDataToolKitHelper {
private final static String TAG = "SecureDataToolKitHelper";
private final static SimpleDateFormat timeStampSimpleDateFormat =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void uploadAll(Context context, RuntimeExceptionDao<EventModel, UUID> eventDao) {
List<EventModel> eventModels = eventDao.queryForAll();
QueryBuilder<EventModel, UUID> eventsQuery = eventDao.queryBuilder();
String[] columns = {...};
eventsQuery.selectColumns(columns);
try {
List<EventModel> models;
models = eventsQuery.orderBy("timeStamp", false).query();
if (models == null || models.size() == 0) {
return;
}
ArrayList<PayloadSecureDataToolKit> toSendList = new ArrayList<>();
for (EventModel eventModel : models) {
try {
PayloadSecureDataToolKit payloadSecureDataToolKit = new PayloadSecureDataToolKit();
if (eventModel != null) {
// map my items ... not shown
toSendList.add(payloadSecureDataToolKit);
}
} catch (Exception e) {
Log.e(TAG, "Error adding payload! " + e + " ..... Skipping entry");
}
}
doAllNetworkCalls(toSendList);
} catch (SQLException e) {
e.printStackTrace();
}
}
my Retrofit stuff
public class ClientSecureDataToolKit {
private static ClientSecureDataToolKit mClientSecureDataToolKit;
private static Retrofit mRetrofit;
private ClientSecureDataToolKit(){
mRetrofit = new Retrofit.Builder()
.baseUrl(Utilities.getSecureDataToolkitURL())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static ClientSecureDataToolKit getClientSecureDataKit(){
if(mClientSecureDataToolKit == null){
mClientSecureDataToolKit = new ClientSecureDataToolKit();
}
return mClientSecureDataToolKit;
}
public Observable<Record> putUserDataToSDK(PayloadSecureDataToolKit payloadSecureDataToolKit){
InterfaceSecureDataToolKit interfaceSecureDataToolKit = mRetrofit.create(InterfaceSecureDataToolKit.class);
Observable<Record> observable = interfaceSecureDataToolKit.putRecord(NetworkUtils.SECURE_DATA_TOOL_KIT_AUTH, payloadSecureDataToolKit);
return observable;
}
}
public interface InterfaceSecureDataToolKit {
#Headers({
"Content-Type: application/json"
})
#POST("/api/create")
Observable<Record> putRecord(#Query("api_token") String api_token, #Body PayloadSecureDataToolKit payloadSecureDataToolKit);
}
Update. I have been trying to apply this answer to not much luck. I am running out of steam for tonight. I am trying to implement this as a unit test, like I did for the original call for one item.. It looks like something is not right with use of lambda maybe..
public class RxJavaBatchTest {
Context context;
final static List<EventModel> models = new ArrayList<>();
#Before
public void before() throws Exception {
context = new MockContext();
EventModel eventModel = new EventModel();
//manually set all my eventmodel data here.. not shown
eventModel.setSampleId("SAMPLE0");
models.add(eventModel);
eventModel.setSampleId("SAMPLE1");
models.add(eventModel);
eventModel.setSampleId("SAMPLE3");
models.add(eventModel);
}
#Test
public void testSetupData() {
Assert.assertEquals(3, models.size());
}
#Test
public void testBatchSDK_Upload() {
Callable<List<EventModel> > callable = new Callable<List<EventModel> >() {
#Override
public List<EventModel> call() throws Exception {
return models;
}
};
Observable.fromCallable(callable)
.flatMapIterable(models -> models)
.flatMap(eventModel -> {
PayloadSecureDataToolKit payloadSecureDataToolKit = new PayloadSecureDataToolKit(eventModel);
return doNetworkCall(payloadSecureDataToolKit) // I assume this is just my normal network call.. I am getting incompatibility errors when I apply a testsubscriber...
.subscribeOn(Schedulers.io());
}, true, 1);
}
private Observable<Record> doNetworkCall(PayloadSecureDataToolKit payloadSecureDataToolKit) {
ClientSecureDataToolKit clientSecureDataToolKit = ClientSecureDataToolKit.getClientSecureDataKit();
Observable observable = clientSecureDataToolKit.putUserDataToSDK(payloadSecureDataToolKit);//.subscribe((Observer<? super Record>) testSubscriber);
return observable;
}
Result is..
An exception has occurred in the compiler (1.8.0_112-release). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
com.sun.tools.javac.code.Symbol$CompletionFailure: class file for java.lang.invoke.MethodType not found
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:compile<MyBuildFlavorhere>UnitTestJavaWithJavac'.
> Compilation failed; see the compiler error output for details.
Edit. No longer trying Lambdas. Even after setting up the path on my mac, javahome to point to 1.8, etc. I could not get it to work. If this was a newer project I would push harder. However as this is an inherited android application written by web developers trying android, it is just not a great option. Nor is it worth the time sink to get it working. Already into the days of this assignment instead of the half day it should have taken.
I could not find a good non lambda flatmap example. I tried it myself and it was getting messy.
If I understand you correctly, you want to make your calls in parallel?
So rx-y way of doing this would be something like:
Observable.fromCallable(() -> eventsQuery.orderBy("timeStamp", false).query())
.flatMapIterable(models -> models)
.flatMap(model -> {
// map your model
//avoid throwing exceptions in a chain, just return Observable.error(e) if you really need to
//try to wrap your methods that throw exceptions in an Observable via Observable.fromCallable()
return doNetworkCall(someParameter)
.subscribeOn(Schedulers.io());
}, true /*because you don't want to terminate a stream if error occurs*/, maxConcurrent /* specify number of concurrent calls, typically available processors + 1 */)
.subscribe(result -> {/* handle result */}, error -> {/* handle error */});
In your ClientSecureDataToolKit move this part into constructor
InterfaceSecureDataToolKit interfaceSecureDataToolKit = mRetrofit.create(InterfaceSecureDataToolKit.class);
I have an akka (akka-actor_2.11) application that we use for stress testing one of our systems. The top level actor called RunCoordinatorActor is able to know based on responses coming from its subordinates when the work is finished.
When the work is finished the RunCoordinatorActor makes a call to getContext().system().shutdown() and then in the main method there is a loop checking for the system.isTerminated() call to return true. All works fine and I am happy with the way it works. However both system.sutdown() and system.isTerminated() methods are marked as deprecated and I am trying to figure out the right way to implement a graceful shutdown without using them.
Here is my main class:
public static void main(String[] args) throws Exception {
if (new ArgumentsValidator().validate(args)) {
// If the arguments are valid then we can load spring application
// context on here.
final ApplicationContext context = new AnnotationConfigApplicationContext(
M6ApplicationContext.class);
// Use an akka system to be able to send messages in parallel
// without doing the low level thread manipulation ourselves.
final ActorSystem system = context.getBean(ActorSystem.class);
final ActorRef runCoordinator = system.actorOf(SPRING_EXT_PROVIDER.get(system)
.props("RunCoordinatorActor"), "runCoordinator");
Thread.sleep(1000);
runCoordinator.tell(new StartTesting(), ActorRef.noSender());
do {
LOGGER.info("Waiting for the process to finish");
Thread.sleep(60000L);
// What would be the alternative for isTerminated() code below
} while (!system.isTerminated());
}
}
and here is my call to shutdown inside the RunCoordinator class:
#Named("RunCoordinatorActor")
#Scope("prototype")
public class RunCoordinator extends UntypedActor {
#Override
public void onReceive(Object message) throws Exception {
....
if (message instanceof WorkDone) {
getContext().system().shutdown();
}
}
}
I can see there is another method called terminate() that returns a Future and if I replace the shutdown call with that it all works OK too.
if (message instanceof WorkDone) {
Future<Terminated> work = getContext().system().terminate();
// But where should I put the call work.isCompleted()
// and how would I make the main aware of it
}
I could find some scala examples on here shutdown-patterns-in-akka-2 but they still use system.shutdown in the end so not sure how up to date that post still is.
Thank you in advance for your inputs.
The solution was not that hard to find once I looked closer into the ActorSystem API.
All I had to do was to add this to my RunCoordinator class:
if (message instanceof WorkDone) {
getContext().system().terminate();
}
And had a Future<Terminated> workDone = system.whenTerminated(); defined in my main class which after the change became:
public static void main(String[] args) throws Exception {
if (new ArgumentsValidator().validate(args)) {
// If the arguments are valid then we can load spring application
// context on here.
final ApplicationContext context = new AnnotationConfigApplicationContext(
M6ApplicationContext.class);
// Use an akka system to be able to send messages in parallel
// without doing the low level thread manipulation ourselves.
final ActorSystem system = context.getBean(ActorSystem.class);
final Future<Terminated> workDone = system.whenTerminated();
final ActorRef runCoordinator = system.actorOf(SPRING_EXT_PROVIDER.get(system)
.props("RunCoordinatorActor"), "runCoordinator");
runCoordinator.tell(new StartTesting(), ActorRef.noSender());
do {
LOGGER.info("Waiting for the process to finish");
Thread.sleep(60000L);
} while (!workDone.isCompleted());
}
}
All worked very well after this. I am still surprised google cold not take me to any existing example showing how to do it.
I'm newbie to Apache Camel. In hp nonstop there is a Receiver that receives events generated by event manager assume like a stream. My goal is to setup a consumer end point which receives the incoming message and process it through Camel.
Another end point I simply need to write it in logs. From my study I understood that for Consumer end point I need to create own component and configuration would be like
from("myComp:receive").to("log:net.javaforge.blog.camel?level=INFO")
Here is my code snippet which receives message from event system.
Receive receive = com.tandem.ext.guardian.Receive.getInstance();
byte[] maxMsg = new byte[500]; // holds largest possible request
short errorReturn = 0;
do { // read messages from $receive until last close
try {
countRead = receive.read(maxMsg, maxMsg.length);
String receivedMessage=new String(maxMsg, "UTF-8");
//Here I need to handover receivedMessage to camel
} catch (ReceiveNoOpeners ex) {
moreOpeners = false;
} catch(Exception e) {
moreOpeners = false;
}
} while (moreOpeners);
Can someone guide with some hints how to make this as a Consumer.
The 10'000 feet view is this:
You need to start out with implementing a component. The easiest way to get started is to extend org.apache.camel.impl.DefaultComponent. The only thing you have to do is override DefaultComponent::createEndpoint(..). Quite obviously what it does is create your endpoint.
So the next thing you need is to implement your endpoint. Extend org.apache.camel.impl.DefaultEndpoint for this. Override at the minimum DefaultEndpoint::createConsumer(Processor) to create your own consumer.
Last but not least you need to implement the consumer. Again, best ist to extend org.apache.camel.impl.DefaultConsumer. The consumer is where your code has to go that generates your messages. Through the constructor you receive a reference to your endpoint. Use the endpoint reference to create a new Exchange, populate it and send it on its way along the route. Something along the lines of
Exchange ex = endpoint.createExchange(ExchangePattern.InOnly);
setMyMessageHeaders(ex.getIn(), myMessagemetaData);
setMyMessageBody(ex.getIn(), myMessage);
getAsyncProcessor().process(ex, new AsyncCallback() {
#Override
public void done(boolean doneSync) {
LOG.debug("Mssage was processed " + (doneSync ? "synchronously" : "asynchronously"));
}
});
I recommend you pick a simple component (DirectComponent ?) as an example to follow.
Herewith adding my own consumer component may help someone.
public class MessageConsumer extends DefaultConsumer {
private final MessageEndpoint endpoint;
private boolean moreOpeners = true;
public MessageConsumer(MessageEndpoint endpoint, Processor processor) {
super(endpoint, processor);
this.endpoint = endpoint;
}
#Override
protected void doStart() throws Exception {
int countRead=0; // number of bytes read
do {
countRead++;
String msg = String.valueOf(countRead)+" "+System.currentTimeMillis();
Exchange ex = endpoint.createExchange(ExchangePattern.InOnly);
ex.getIn().setBody(msg);
getAsyncProcessor().process(ex, new AsyncCallback() {
#Override
public void done(boolean doneSync) {
log.info("Mssage was processed " + (doneSync ? "synchronously" : "asynchronously"));
}
});
// This is an echo server so echo request back to requester
} while (moreOpeners);
}
#Override
protected void doStop() throws Exception {
moreOpeners = false;
log.debug("Message processor is shutdown");
}
}
I'm working on an application that uses Websockets (Java EE 7) to send messages to all the connected clients asynchronously. The server (Websocket endpoint) should send these messages whenever a new article (an engagement modal in my app) is created.
Everytime a connection is established to the websocket endpoint, I'm adding the corresponding session to a list, which I could be able to access outside.
But the problem I had is, when I'm accessing this created websocket endpoint to which all the clients connected from outside (any other business class), I've get the existing instance (like a singleton).
So, can you please suggest me a way I can get an existing instance of the websocket endpoint, as I can't create it as new MyWebsocketEndPoint() coz it'll be created by the websocket internal mechanism whenever the request from a client is received.
For a ref:
private static WebSocketEndPoint INSTANCE = null;
public static WebSocketEndPoint getInstance() {
if(INSTANCE == null) {
// Instead of creating a new instance, I need an existing one
INSTANCE = new WebSocketEndPoint ();
}
return INSTANCE;
}
Thanks in advance.
The container creates a separate instance of the endpoint for every client connection, so you can't do what you're trying to do. But I think what you're trying to do is send a message to all the active client connections when an event occurs, which is fairly straightforward.
The javax.websocket.Session class has the getBasicRemote method to retrieve a RemoteEndpoint.Basic instance that represents the endpoint associated with that session.
You can retrieve all the open sessions by calling Session.getOpenSessions(), then iterate through them. The loop will send each client connection a message. Here's a simple example:
#ServerEndpoint("/myendpoint")
public class MyEndpoint {
#OnMessage
public void onMessage(Session session, String message) {
try {
for (Session s : session.getOpenSessions()) {
if (s.isOpen()) {
s.getBasicRemote().sendText(message);
}
} catch (IOException ex) { ... }
}
}
But in your case, you probably want to use CDI events to trigger the update to all the clients. In that case, you'd create a CDI event that a method in your Websocket endpoint class observes:
#ServerEndpoint("/myendpoint")
public class MyEndpoint {
// EJB that fires an event when a new article appears
#EJB
ArticleBean articleBean;
// a collection containing all the sessions
private static final Set<Session> sessions =
Collections.synchronizedSet(new HashSet<Session>());
#OnOpen
public void onOpen(final Session session) {
// add the new session to the set
sessions.add(session);
...
}
#OnClose
public void onClose(final Session session) {
// remove the session from the set
sessions.remove(session);
}
public void broadcastArticle(#Observes #NewArticleEvent ArticleEvent articleEvent) {
synchronized(sessions) {
for (Session s : sessions) {
if (s.isOpen()) {
try {
// send the article summary to all the connected clients
s.getBasicRemote().sendText("New article up:" + articleEvent.getArticle().getSummary());
} catch (IOException ex) { ... }
}
}
}
}
}
The EJB in the above example would do something like:
...
#Inject
Event<ArticleEvent> newArticleEvent;
public void publishArticle(Article article) {
...
newArticleEvent.fire(new ArticleEvent(article));
...
}
See the Java EE 7 Tutorial chapters on WebSockets and CDI Events.
Edit: Modified the #Observer method to use an event as a parameter.
Edit 2: wrapped the loop in broadcastArticle in synchronized, per #gcvt.
Edit 3: Updated links to Java EE 7 Tutorial. Nice job, Oracle. Sheesh.
Actually, WebSocket API provides a way how you can control endpoint instantiation. See https://tyrus.java.net/apidocs/1.2.1/javax/websocket/server/ServerEndpointConfig.Configurator.html
simple sample (taken from Tyrus - WebSocket RI test):
public static class MyServerConfigurator extends ServerEndpointConfig.Configurator {
public static final MyEndpointAnnotated testEndpoint1 = new MyEndpointAnnotated();
public static final MyEndpointProgrammatic testEndpoint2 = new MyEndpointProgrammatic();
#Override
public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
if (endpointClass.equals(MyEndpointAnnotated.class)) {
return (T) testEndpoint1;
} else if (endpointClass.equals(MyEndpointProgrammatic.class)) {
return (T) testEndpoint2;
}
throw new InstantiationException();
}
}
You need to register this to an endpoint:
#ServerEndpoint(value = "/echoAnnotated", configurator = MyServerConfigurator.class)
public static class MyEndpointAnnotated {
#OnMessage
public String onMessage(String message) {
assertEquals(MyServerConfigurator.testEndpoint1, this);
return message;
}
}
or you can use it with programmatic endpoints as well:
public static class MyApplication implements ServerApplicationConfig {
#Override
public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses) {
return new HashSet<ServerEndpointConfig>
(Arrays.asList(ServerEndpointConfig.Builder
.create(MyEndpointProgrammatic.class, "/echoProgrammatic")
.configurator(new MyServerConfigurator())
.build()));
}
#Override
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
return new HashSet<Class<?>>(Arrays.asList(MyEndpointAnnotated.class));
}
Of course it is up to you if you will have one configurator used for all endpoints (ugly ifs as in presented snippet) or if you'll create separate configurator for each endpoint.
Please do not copy presented code as it is - this is only part of Tyrus tests and it does violate some of the basic OOM paradigms.
See https://github.com/tyrus-project/tyrus/blob/1.2.1/tests/e2e/src/test/java/org/glassfish/tyrus/test/e2e/GetEndpointInstanceTest.java for complete test.