Hi BogDan,<div><br></div><div>Good point. I assume you are referring to native libraries being able to access <i>other</i> native libraries loaded by different class loaders in Java? If so, we should ask about it, but I really don't think it would break. It's pretty low-level stuff that allows dynamically-linked code to be found, used, and reused within a process. So breaking this would mean changing the OS/kernel itself in a non-standards-compliant way (unlikely.) Or the JVM somehow splitting our single application/activity into more than one process, which is also unlikely and would contradict some of the documentation for Activity (thus breaking other apps.) If there are other ways it could break, I don't see them.</div>
<div><br></div><div>That said, it's always a good idea to ask. Let me know if we're thinking of the same thing or not. I'm willing to post to android-ndk, but you're welcome to do it instead.</div><div><br>
</div><div>Have a great day!</div><div>Tyler<br><br><div class="gmail_quote">On Thu, Jan 26, 2012 at 2:48 AM, BogDan <span dir="ltr"><<a href="mailto:bog_dan_ro@yahoo.com" target="_blank">bog_dan_ro@yahoo.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Tyler,<br>
<br>
<br>
The big question is if Google can change android in order to hide the symbols if they are loaded by different classloaders ?<br>
<br>
If they can't do it, I think your solution is ok, but if it is possible to do it, then we risk to break everyones applications !<br>
<br>
<br>
Before we make a decision I think we should ask google if they are planning to change current behavior or not. Do you want to open a topic to android-ndk[1] or should I do ?<br>
<br>
<br>
Cheers,<br>
BogDan.<br>
<br>
<br>
[1] <a href="http://groups.google.com/group/android-ndk" target="_blank">http://groups.google.com/group/android-ndk</a><br>
<div><br>
>________________________________<br>
> From: Tyler Mandry <<a href="mailto:tmandry@gmail.com" target="_blank">tmandry@gmail.com</a>><br>
</div>>To: <a href="mailto:necessitas-devel@kde.org" target="_blank">necessitas-devel@kde.org</a><br>
>Sent: Monday, January 23, 2012 7:40 AM<br>
>Subject: Allowing Java-C++ interaction<br>
<div><div>><br>
><br>
>This accidentally didn't get sent to the list; forwarding. Sorry about that.<br>
><br>
><br>
>---------- Forwarded message ----------<br>
>From: Tyler Mandry <<a href="mailto:tmandry@gmail.com" target="_blank">tmandry@gmail.com</a>><br>
>Date: Tue, Jan 17, 2012 at 12:19 AM<br>
>Subject: Re: Allowing Java-C++ interaction<br>
>To: BogDan <<a href="mailto:bog_dan_ro@yahoo.com" target="_blank">bog_dan_ro@yahoo.com</a>><br>
><br>
><br>
>Hi BogDan,<br>
><br>
><br>
>That definitely could work. But it does add to the complexity, and possibly start-up time, of the app. An alternative solution would be: simply to load the bundled libs in the main classloader, UNLESS they are bundled Qt libs that are used by the .jar, in which case they are loaded in the child CL. This could be accomplished by separating these two kinds of libs into different categories, or even auto-detecting them by their names at runtime. What do you think?<br>
><br>
><br>
>(One thing I've found: native libs loaded in different classloaders can always talk to each other, since they're part of the same process. In other words, you could load core Qt libs in the child CL and QtWebKit in the parent CL and it will all work. I don't know if this is useful but thought it might be.)<br>
><br>
><br>
>Thanks,<br>
>Tyler<br>
><br>
><br>
><br>
>On Mon, Jan 16, 2012 at 2:22 AM, BogDan <<a href="mailto:bog_dan_ro@yahoo.com" target="_blank">bog_dan_ro@yahoo.com</a>> wrote:<br>
><br>
>Hi Tyler,<br>
>><br>
>><br>
>><br>
>><br>
>> Thanks you for sharing this with us, it helped me to understand better what is the problem.<br>
>>I also check your patch [1] but it doesn't seem to fix all the problems, bundle libs will have the same problem, so I tried to find another solution which hopefully will handle all this situations. The solution is create a separate package with your own java files, and this package to be loaded by the same class loaded which loads the plugin .jar files.<br>
>><br>
>><br>
>><br>
>>Please let me know if this approach is ok for you.<br>
>><br>
>><br>
>><br>
>><br>
>><br>
>>Cheers,<br>
>>BogDan.<br>
>><br>
>><br>
>><br>
>>[1] <a href="http://sourceforge.net/p/necessitas/tickets/140/" target="_blank">http://sourceforge.net/p/necessitas/tickets/140/</a><br>
>><br>
>><br>
>><br>
>><br>
>><br>
>><br>
>>>________________________________<br>
>>> From: Tyler Mandry <<a href="mailto:tmandry@gmail.com" target="_blank">tmandry@gmail.com</a>><br>
>>>To: BogDan <<a href="mailto:bog_dan_ro@yahoo.com" target="_blank">bog_dan_ro@yahoo.com</a>><br>
>>>Sent: Friday, January 13, 2012 6:43 AM<br>
>>>Subject: Re: Allowing Java-C++ interaction<br>
>>><br>
>>><br>
>>><br>
>>>Hi BogDan,<br>
>>><br>
>>><br>
>>>What currently happens is the native library is loaded in the child class loader (by the code in the .jar, in fact,) so application code (loaded by the parent class loader) can't see any native functions loaded by the native library. And no, I don't try to access anything in the .jar in my application.<br>
>>><br>
>>><br>
>>>I did make a simple testcase that fails before the patch and works after. Since the patch involves changing QtActivity.java, it's difficult to send a complete project and see the before and after. Instead, do the following:<br>
</div></div>>>> 1. Create a new Qt Quick Application project in Qt Creator, with an Android target<br>
>>> 2. (i) Replace main.cpp with the attached main.cpp, and (ii) add in the Java source to the tree (copy the android/src/org/kde/necessitas/example folder in attached archive to android/src/org/kde/necessitas in the project)<br>
>>> 3. Go to QtActivity.java and add (i) "import org.kde.necessitas.example.simpleapp.MyNative;" at the top, and (ii) the following at the END of loadApplication():<br>
<div><div>>>>//dostuffafter loading<br>
>>>MyNativenat=newMyNative();<br>
>>>nat.doSomething();<br>
>>><br>
>>><br>
>>>[Modifying QtActivity.java is currently the only way I know to run your own Java code as the application loads.]<br>
>>><br>
>>><br>
>>>After that, run the project and you should see "No implementation found for native Lorg/kde/necessitas/example/simpleapp/MyNative;.doSomething ()V" along with an UnsatisfiedLinkError in the log.<br>
>>><br>
>>><br>
>>>Then point Qt Creator to a build of Qt with the patch and do the process again with that version of Qt. (**Of course you'll need to deploy and use local Qt libs!**) You should see "This is a native function, doing something!!" in the logs, and no crash.<br>
>>><br>
>>><br>
>>>I hope this is clear enough and that it sheds some light on what I'm trying to accomplish :). Let me know if anything is unclear.<br>
>>><br>
>>><br>
>>>Thanks for all your hard work!!<br>
>>>Tyler<br>
>>><br>
>>><br>
>>><br>
>>>On Thu, Jan 12, 2012 at 8:46 AM, BogDan <<a href="mailto:bog_dan_ro@yahoo.com" target="_blank">bog_dan_ro@yahoo.com</a>> wrote:<br>
>>><br>
>>>Hi Tyler,<br>
>>>><br>
>>>> I reviewed my code and seems to be ok, when I create m_classLoader (check QtActivity.java) I pass its parent correctly, so, even if your library is loaded by a class which was loaded by m_classLoader and there your package is not visible, m_classLoader should search also into its parent for that class.<br>
>>>><br>
>>>> I hope your package don't try to access classes from .jar file, because those classes are private, and they should be used *ONLY* by platform plugin.<br>
>>>><br>
>>>><br>
>>>>Would you please create a simple example which fails, it will help me to understand the problem better ?<br>
>>>><br>
>>>><br>
>>>>Thank you !<br>
>>>><br>
>>>><br>
>>>>Cheers,<br>
>>>>BogDan.<br>
>>>><br>
>>>><br>
>>>>+ CC: necessitas-devel<br>
>>>><br>
>>>><br>
>>>><br>
>>>>><br>
>>>>><br>
>>>>>Hi BogDan,<br>
>>>>><br>
>>>>><br>
>>>>>No worries, I just didn't want it to be overlooked :)<br>
>>>>><br>
>>>>><br>
>>>>>In a nutshell, any (user) Java code the application had couldn't see the user's native JNI code, because their native library was loaded in a class loader that was different from the (primary) class loader that their Java code ran in. This upset a few people that have custom Java and JNI code, like me :). The only way to make calls between different class loaders is to use reflection, so instead I made a way for the application native library to be loaded in the primary class loader.<br>
>>>>><br>
>>>>><br>
>>>>>That was a mouthful, but I hope it helps. Let me know if you have further questions!<br>
>>>>><br>
>>>>><br>
>>>>>Thanks,<br>
>>>>>Tyler<br>
>>>>><br>
>>>>><br>
>>>>>On Tue, Jan 10, 2012 at 1:49 PM, BogDan <<a href="mailto:bog_dan_ro@yahoo.com" target="_blank">bog_dan_ro@yahoo.com</a>> wrote:<br>
>>>>><br>
>>>>>Hi Tyler,<br>
>>>>>><br>
>>>>>>Please accept my apologize for slow reply.<br>
>>>>>><br>
>>>>>>I need a few days to understand what is wrong with current design and to check your patch, then I'll come back with feedback !<br>
>>>>>><br>
>>>>>>Thank you very much for your patience !<br>
>>>>>><br>
>>>>>>Cheers,<br>
>>>>>>BogDan.<br>
>>>>>><br>
>>>>>><br>
>>>>>><br>
>>>>>><br>
>>>>>><br>
>>>>>>><br>
>>>>>>><br>
>>>>>>>BogDan,<br>
>>>>>>><br>
>>>>>>><br>
>>>>>>>Do you think this patch can be included in the next alpha? If not, what needs to be done?<br>
>>>>>>><br>
>>>>>>><br>
>>>>>>>Thanks,<br>
>>>>>>>Tyler<br>
>>>>>>><br>
>>>>>>><br>
>>>>>>><br>
>>>>>>>On Thu, Dec 29, 2011 at 12:48 AM, Tyler Mandry <<a href="mailto:tmandry@gmail.com" target="_blank">tmandry@gmail.com</a>> wrote:<br>
>>>>>>><br>
>>>>>>>Here is the patch (against alpha4 head 2469081) to make everything work. I've tested and it works. The basic approach is to compile qtmain_android.cpp into its own .so during Qt compilation, and load it in the application. It uses dynamic linker calls to find the main() function at runtime. So there is no awkward back-and-forth library loading needed after all.<br>
>>>>>>>><br>
>>>>>>>><br>
>>>>>>>>Backward compatibility: I made sure my changes to the JAR allowed it to still work with existing built applications as-is, and light testing confirms that it is. This required a few extra lines that are marked as such in case you want to remove them.<br>
>>>>>>>><br>
>>>>>>>><br>
>>>>>>>>I didn't touch Ministro, however, and I suspect that my addition to lib/rules.xml will cause new versions of Ministro to try to load libqtmain.so, which won't exist in old/current applications. I'll leave that issue for someone more familiar with Ministro to look at, if it's a concern.<br>
>>>>>>>><br>
>>>>>>>><br>
>>>>>>>>Finally, I mentioned creating a new category of user-defined bundled libs in case the user wants to use JNI with those libs, but did not implement that.<br>
>>>>>>>><br>
>>>>>>>><br>
>>>>>>>>I hope you like it and that it can be included in the next alpha. Let me know if you have any questions or comments :)<br>
>>>>>>>>Tyler<br>
>>>>>>>><br>
>>>>>>>><br>
>>>>>>>>On Sat, Dec 24, 2011 at 11:28 PM, Tyler Mandry <<a href="mailto:tmandry@gmail.com" target="_blank">tmandry@gmail.com</a>> wrote:<br>
>>>>>>>><br>
>>>>>>>>BogDan,<br>
>>>>>>>>><br>
>>>>>>>>><br>
>>>>>>>>>Merry Christmas again! When you have time:<br>
>>>>>>>>><br>
>>>>>>>>><br>
>>>>>>>>>Separating out qtmain_android.cpp into its own shared lib allows us to build it during the Qt build rather than with the application projects. (We have to remove the --no-undefined linker option, but it works.) My question is, where should that library go in the Qt install? It isn't technically a Qt plugin, so I don't know about putting it with plugins, and lib/ is all official Qt libs. It fits in best with jar/, but then the directory name doesn't make sense :). We could also make another directory, though it seems unnecessary. I'll probably stick it in jar/ unless I hear from you.<br>
>>>>>>>>><br>
>>>>>>>>><br>
>>>>>>>>>I've proved that this method works, and now I'm just working on integrating all the changes in code.<br>
>>>>>>>>><br>
>>>>>>>>><br>
>>>>>>>>>Cheers,<br>
>>>>>>>>>Tyler<br>
>>>>>>>>><br>
>>>>>>>>><br>
>>>>>>>>><br>
>>>>>>>>>On Fri, Dec 23, 2011 at 2:14 AM, Tyler Mandry <<a href="mailto:tmandry@gmail.com" target="_blank">tmandry@gmail.com</a>> wrote:<br>
>>>>>>>>><br>
>>>>>>>>>One thing I've encountered: If I'm not mistaken, people can/will use bundled libraries to bundle Qt libraries along with their application (to bypass Ministro.) Others will use bundled libs of their own for other purposes. We will want to load the Qt bundled libs inside the child class loader, so our JAR can talk to them, and the other bundled libs inside the main Java class loader, in case they want to interact with those native bundled libs via JNI. This will require us to make a new distinction on the type of bundled library.<br>
>>>>>>>>>><br>
>>>>>>>>>>Other thoughts: I've been looking and it looks like this isn't a difficult change to make. It's very minimal in the way it changes how things are done right now. It does require a change to the JAR files to accomodate for that back-and-forth lib loading that I described. Anyway, I plan to implement all this tomorrow and see how it goes.<br>
>>>>>>>>>><br>
>>>>>>>>>><br>
>>>>>>>>>>On Thu, Dec 22, 2011 at 8:51 PM, Tyler Mandry <<a href="mailto:tmandry@gmail.com" target="_blank">tmandry@gmail.com</a>> wrote:<br>
>>>>>>>>>><br>
>>>>>>>>>>Hi all, and Merry Christmas.<br>
>>>>>>>>>>><br>
>>>>>>>>>>><br>
>>>>>>>>>>>We were discussing the importance of allowing Java and C++ to interact for many people's apps in android-qt (thread: C++ and Java interaction in Alpha3.) With the new separation of the JAR files, and use of a different class loader for the app code, it has become very difficult to allow this. Traditional native interface classes can no longer see the native methods that are loaded by the separate class loader.<br>
>>>>>>>>>>><br>
>>>>>>>>>>><br>
>>>>>>>>>>>I did some playing around, and I think I found a simple solution that works. If we separate out the code in qtmain_android.cpp into its own (very small!) shared library, and allow the user's application code to be in one library all by itself, we can load them in separate class loaders. While you can't do Java-Java or Java-native interaction easily across the class loader barrier, native-native interaction works fine since it's all the same process. Simply load the Qt library in the /child/ class loader, followed by the application code library in the /main/ class loader, followed by the qtmain_android code in the /child/ class loader. Then the user's Java code can see the user's C++ code and vice versa, because they are all loaded under the same class loader.<br>
>>>>>>>>>>><br>
>>>>>>>>>>><br>
>>>>>>>>>>>I did a testcase of this (with libraries of my own, not Qt) and confirmed that it works in a simple case. If no one sees any problems with this let's implement it.<br>
>>>>>>>>>>>--<br>
>>>>>>>>>>>Tyler Mandry<br>
>>>>>>>>>>><br>
>>>>>>>>>><br>
>>>>>>>>>><br>
>>>>>>>>>><br>
>>>>>>>>>>--<br>
>>>>>>>>>>Tyler Mandry<br>
>>>>>>>>>><br>
>>>>>>>>><br>
>>>>>>>><br>
>>>>>>>><br>
>>>>>>>><br>
>>>>>>>>--<br>
>>>>>>>>Tyler Mandry<br>
>>>>>>>><br>
>>>>>>><br>
>>>>>>><br>
>>>>>>><br>
>>>>>>>--<br>
>>>>>>>Tyler Mandry<br>
>>>>>>><br>
>>>>>>><br>
>>>>>>><br>
>>>>>><br>
>>>>><br>
>>>>><br>
>>>>><br>
>>>>>--<br>
>>>>>Tyler Mandry<br>
>>>>><br>
>>>>><br>
>>>>><br>
>>>><br>
>>><br>
>>><br>
>>><br>
><br>
><br>
><br>
>--<br>
>Tyler Mandry<br>
><br>
><br>
><br>
><br>
>--<br>
>Tyler Mandry<br>
><br>
</div></div>>_______________________________________________<br>
>Necessitas-devel mailing list<br>
><a href="mailto:Necessitas-devel@kde.org" target="_blank">Necessitas-devel@kde.org</a><br>
><a href="https://mail.kde.org/mailman/listinfo/necessitas-devel" target="_blank">https://mail.kde.org/mailman/listinfo/necessitas-devel</a><br>
><br>
><br>
><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>Tyler Mandry<br>
</div>