Re: Wrapper Module - compile and provided dependencies?
geertjan wielenga <[email protected]> Sun, 4 Jun 2017 12:28:59 +0200
| Newsgroups | gmane.comp.java.netbeans.modules.openide.devel |
|---|---|
| Organization | Oracle Corporation |
| Message-ID | <[email protected]> |
Wow, looks like a great demo -- and exactly something many have been asking about over the years. Thanks a lot. Gj On 30-5-2017 17:48, Boris Heithecker wrote: > I've put a demo on github: > > https://github.com/borisheithecker/nbpayara-demo > <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] > <mailto:[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 > <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] > <mailto:[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