Re: Wrapper Module - compile and provided dependencies?
Boris Heithecker <[email protected]> Tue, 30 May 2017 17:48:57 +0200
| Newsgroups | gmane.comp.java.netbeans.modules.openide.devel |
|---|---|
| Message-ID | <CAL465RFWhhO0bC=MPK1LYW=9rc4FSP7XVoDK5BHW4sTBrpA4cw@mail.gmail.com> |
I've put a demo on github: https://github.com/borisheithecker/nbpayara-demo It shows how to call EJBs and receive JMS messages on top of the NetBeans platform. Boris 2017-05-14 19:10 GMT+02:00 Boris Heithecker <[email protected]>: > Hi Kevin, > > a NamingException is mostly only a wrapper for some other exception that > happened during the look-up. So, can you provide any stack trace? Also, > please show the lines of code where you create the initial context and then > look up the remote bean. > > One problem is that glassfish/payara is not fully compliant with the > NetBeans classloader system. When a remote bean is being looked up for the > first time, the iiop infrastructure creates an implementation stub of the > remote interface at runtime, i.e. it generates java bytecode (using a > library called Primitive Function Library). The new class is defined on the > invoking thread's context classloader (using java reflection API), which in > NetBeans is the so called system classloader. The problem is that this > "system classloader" is a purely delegating classloader. It delegates all > calls to one of its multiple parents, which are the module classloaders. > Because of this, while it is possible to define an implementation class at > runtime on the system classloader, this classloader will never find them > afterwards. This causes an exception, which is then possibly wrapped into a > NamingException. My workaround is to simply replace the context classloader > only during the look-up with a classloader which itself has the system > classloader as its parent. > > I've uploaded a part of my own implementation to github ( > https://github.com/borisheithecker/nbpayara-spi/blob/master > /src/main/java/org/nbpayara/spi/DefaultRemoteLookup.java ). Method > doLookup(final String name, final Class<T> clz, Properties props) is > where the actual look-up is done. The endpoints property is not needed if > you specify the remote host and port. I'll also try to find some time and > set up a small demo application. > > Also, for a start, don't run the server on the same physical machine as > the NetBeans client. This would need a little bit more configuration and > will fail otherwise. > Which libraries do you bundle? payara-embedded-all (all glassfish in one > jar, from Maven) plus the jar containing your beans should do. > Futher, you have to use the jndi names starting with "java:global/....". > These names are available from the server log file after deployment. > > Good luck! > Boris > > > 2017-05-12 16:12 GMT+02:00 kpenrose <[email protected]>: > >> Boris, >> It's been a while since I started this project, and I had switched to >> using webservices because they were so easy to implement and they worked >> rather well with the NetBeans RCP application. However, as I'm sure you >> know, there are some limitations to what you can do with webservices, and I >> have started to try to replace them with EJBs. As I'm sure you're also >> aware, calling remote EJBs from Netbeans platform apps is a real pain, and >> I notice that you have done just that. >> I've built and deployed the ejb's on my glassfish server (4.1), and I can >> access them and retrieve data from stand-alone, command line apps with no >> problem. I've become very proficient at bundling the correct libraries and >> putting it all together in a netbeans platform application. I have no >> problem getting an initial context, and querying the context for all of the >> available jndi entries. However, when I try to do a look-up on any of >> those jndi entries, I get a naming exception, even though I got the jndi >> name directly from the server. I have tried with both portable and >> non-portable names created by the glassfish server. Nothing works. I have >> the glassfish libraries and the ejb libraries all packaged into one >> netbeans module. When I attempt the lookup, there are no errors on the >> server side, and only the naming exception in the netbeans client. >> There are many stories on the web from people who have exactly the same >> problem, but there doesn't seem to be a solution other than switching to >> JBoss or WebSphere or some other costly solution. I have even tried the >> Payara (Glassfish) server to no avail. >> If you do indeed, have this puzzle figured out, I would love to hear what >> you do did to accomplish this herculean feat! Please do share. I'll >> provide any information you need as to what I've done to get to this point, >> and hopefully you can provide the missing piece to get me to the promised >> land. >> >> Thanks! >> >> >> Boris Heithecker wrote: >> > Hello,yes, it's possible to use jms and remote ejb calls in a NetBeans >> RCP, an application has been running in a production environment for over a >> year now. >> > In my experience, the only viable solution is adding >> glassfish-embedded-all as a library jar plus some adaption to the netbeans >> platform. The all-in-one distribution (glassfish-embedded-all-4.1.jar) >> is only one jar and 87MB, not 400, and you'll hardly get a smaller solution >> if you assemble a working jms message queue from scratch. >> > Other solutions could be 1. launching an external glassfish >> installation in embedded mode - not possible because of netbeans >> classloader issues, 2. lauching an external gf installation as an osgi >> bundle from within nb - not possible because apache felix doesn't comply >> with the nb classloader system here, too. >> > I've added glassfish-embedded-all-4.1.jar to a regular module as an >> additional wrapped jar (Project Properties -> Libraries -> Wrapped JARs >> tab) and exported only the official java ee API packages (Project >> Properties -> API Versioning). This leverages part of the Java EE APi to >> NB. On platform startup, a tiny glassfish domain (domain directory plus >> domain.xml with all unnecessary services removed) contained in the module >> sources under ModuleProjectDir/release is launched - using a custom adapted >> glassfish runtime builder for configuration of the running gf instance. >> > To use jms, you have to add jms resources to the domain.xml, but it >> works even in rather poor network conditions. >> > It's impossible to go into more detail at this place, because, after >> all, using java ee apis on top of the platform is an accumulation of many >> small solutions which can't be given here at full length. But our approach >> is definitely a viable solution, it's even possible to secure ejb remote >> calls and jms connections. >> > For part of my remote database communication, secured webservices are >> used as well, but I've found out that these are definitely slower and could >> become a serious performance issue if you need quick responses to user >> activity. >> > Hope this could help you, >> > Boris >> > >> > >> > >> > >> > 2015-11-12 15:10 GMT+01:00 kpenrose <address-removed (address-removed)>: >> > >> > > I have just started programming on the NetBeans RCP, using maven, >> trying to port some existing JavaFX applications into the platform. The >> JavaFX applications are part of a suite of apps, so I thought it would be >> cool to allow them all to be modules which could be loaded into the >> platform as needed by each group of users. >> > > The JavaFX apps rely heavily on JMS and of course database access. >> Both of these led to huge problems for me on the RCP. I found that adding >> the necessary jar files for remote EJB lookup to be very painful, so I >> switched to webservices (which is very easily done by adding the >> @WebService annotation to the beans - no need for Remote classes, etc.) >> Integrating webservices into the RCP was relatively painless. >> > > However, adding JMS has been another story - and it's still related >> to adding the necessary jar files to the project to allow the stand-alone >> application to access services housed in the glassfish 4.1 server. I've >> tried adding gf-client.jar and imqjmsra.jar from the org.glassfish.main >> branch of the repositories. I tried creating two wrapper modules, one for >> each, and using them in the RCP application. >> > > In each module that uses classes from these wrappers, I added a >> provided dependency, based on the fact that I read that doing so keeps that >> wrapper module from being added to the current module. I obviously need >> the reference to the wrapper module in order to compile my code. After >> following this procedure, I get many ClassNotFound errors when trying to >> run the application. Adding them as compile dependencies removed the >> ClassNotFound errors, but then I get issues of the app trying to load a >> class from two different modules. >> > > For anyone familiar with using gf-client.jar, you also need all of >> the module jars that are found in the $GLASSFISH_HOME/modules directory to >> be on the classpath. Not sure how to wrap up this mess either. I found a >> way around those problems by wrapping the glassfish-embedded-all.jar file, >> which contains everything needed, but again, compile dependencies in each >> module and I end up with a 400MB application. Using this method is the >> only way I have been able to get webservices working AND JMS. >> > > So, my question really boils down to: how do you wrap a jar of jars >> (hundreds) and make them available to all requiring modules in an >> application? Something that seems simple on its cover is turning out to be >> a nightmare for me. >> > > Thanks. >> > > >> > > >> > > >> > > >> > > >> > >> >> >> >> >> >> > > > -- > Boris Heithecker > > > Dr. Boris Heithecker > Lüneburger Str. 30 > 28870 Ottersberg > Tel.: 0 42 05/ 31 58 34 > -- Boris Heithecker Dr. Boris Heithecker Lüneburger Str. 30 28870 Ottersberg Tel.: 0 42 05/ 31 58 34