Android Studio - Include ResourceBundles in Module - android-studio

I currently switched from eclipse to android studio. In eclipse I had 2 projects, one android application project and one java project which I included in the android project as library. This java project uses ResourceBundles to create internationalized error messages for it's own errors. This has been my project structure:
/MyApp
/src
/res
...
/MyLibrary
/src
/res (added as source folder to build path)
/loc
Bundle_en.properties
This worked when loading the RessourceBundles as following:
ResourceBundle.getBundle("loc.Bundle", Locale.ENGLISH);
Now I switched to android studio and my new project structure looks like this (added the java library as module):
/MyProject
/MyApp
...
/MyLibrary
/src
/main
/java
...
/res
/loc
Bundle_en.properties
But I'm not able to load the ResourceBundles anymore, it's just throwing a java.util.MissingResourceException. I tried a lot of different locations for the ResourceBundles and different paths but I'm going to get crazy because nothing seems to work. Could anybody explain where to put those bundles and how to load them?
Thank you!

Faced exactly the same problem. To make it work I finally had to create a resorces folder in my project module's main folder.
here multiple files starting with the same name (as messages in this picture) gets bundled as a resource bundle.
Finally had to call it using
ResourceBundle.getBundle("org.eclipse.paho.client.mqttv3.internal.nls.logcat")
or
ResourceBundle.getBundle("org.eclipse.paho.client.mqttv3.internal.nls.messages")
to get the required resource.

If you include the second project as a library, you might not want to create a new resource folder as suggested in a previous answer (which does work). Instead, you can simply add the library's resource folder to your resource directories in your module's build.gradle: to the android section add
sourceSets {
main.resources.srcDirs += 'path/to/your/libs/res'
}
If now the added res folder contains org/mypackage/Bundle.properties you can refer to it using
ResourceBundle.getBundle("org.mypackage.Bundle")
Actually adding a new resource folder does nothing more then adding it as a resource directory in build.gradle.

I never tried but Intellij comes with very good integration of Resource Bundles.
Refer this link
http://www.jetbrains.com/idea/webhelp/resource-bundle.html
From the link above
Resource bundle is a set of properties files that have same base name
with different language-specific suffixes. A resource bundle contains
at least two properties files with similar base name, for example
file_en.properties and file_de.properties.
IntelliJ IDEA recognizes properties files, and if two or more
properties files with the names that differ only in suffix, are
encountered, joins them into a resource bundle. The new node Resource
Bundle '(base name)' appears in the Project Tool Window:
You can have these files inside your module or on root as well.

First please ensure your resource folder (where the property file is localted) is in the classpath and you can easily find that by calling the following.
URLClassLoader ldr = (URLClassLoader)ClassLoader.getSystemClassLoader();
URL[] urls = ldr.getURLs();
for(URL url : urls)
{
System.out.println(url.getPath());
}
Now if you find your resources folder in the classpath then you can simply call the bundle base name, in your case ResourceBundle.getBundle("Bundle"), no need for a fully qualified path. Assuming you are using English locale, it should find it. You can further add en_US, en_NZ, en_GB etc if needed.
If you do not find your property folder then make sure it is in the classpath and if you need to add it dynamically follow this thread.
How do you change the CLASSPATH within Java?
Remember the only addition for loading property files dynamically is that you MUST call findResource or findResources API on the class loader to load the property file. Hope this helps.

Related

How to import 3rd party binary library in Android Studio 3.4?

Backgroud:
I would like to use a third-party library in Android Studio 3.4. The library includes three files:see pics
arm64-v8a/libAnalyticsLib.so
armeabi-v7a/libAnalyticsLib.so
StrideAnalyticsLib.jar.
The class files within "StrideAnalyticsLib.jar" show that they seem to be generated by using SWIG.
I've tried two ways to import this library but still cannot
import StrideAnalyticsLib.*;
But this doesn't allow to access the classes and shows "cannot
resolve symbol ...".
the .so files are with jniLibs
~/main/jniLibs/
~/main/jniLibs/arm64-v8a/libAnalyticsLib.so
~/main/jniLibs/armeabi/libAnalyticsLib.so
the .so files are within libs; At the same time, i added "sourceSets { main{ jniLibs.srcDirs = ['libs']}}" in build.gradle;
~/libs/
~/libs/arm64-v8a/libAnalyticsLib.so
~/libs/armeabi/libAnalyticsLib.so
Both attempts are followed by cleaning and rebuilding the project.I'm very new to Android and couldn't get it work. Could anyone please provide help? Great Thanks!
After I studied the process using SWIG to wrap c/c++ library into the .jar and .so., I realised that the .jar and .so will have same package name so that the .jar can call the .so file.
Because my .jar doesn't work when it's saved in /libs, I instead copied all classes within the .jar and pasted them into the /main folder. Remember to put them outside your package, otherwise the package name of these classes will be changed, which cause my problem. The way of importing .so is correct. Just put the .so files inside /main/jniLibs.

Spurious module ".." in Android Studio project

I followed the steps in How to share a single library source across multiple projects to add an external library to a project.
My project(s) structure:
Project MyTest1:
Module MyLib
Project MyTest2:
Module MyApp
I edited settings.gradle in MyTest2 and added , ..:MyTest1:MyLib to the include directive. Now, I am able to see and use the external library project from within MyTest2 project. Things work as expected.
However, I see a spurious module ".." alongside MyApp and MyLib. There are no nodes under it and it doesn't seem to cause any problems. I am wondering what exactly is this module for and if there is a way to get rid of it. Regards.
Edit
Both my projects are under a directory C:\MyDev. It appears that, anytime you bring up MyTest2 project, AS modifies a file MyTest2.idea\modules.xml and inserts the following line:
<module fileurl="file://C:/MyDev.iml" filepath="C:/MyDev.iml" />
It then complains that the module was not loaded and creates a fake ".." module. I think this is the root of the problem.
Do not declare ..:MyTest1:MyLib as your include. It will cause many problems. Instead, declare it the following way:
include ':MyLib'
project(':MyLib').projectDir = new File('../MyTest1/MyLib')

How to customize destination path of each dependency

I'm trying to use Gradle to manage dependencies in non-Java projects. The idea is to have a single, generic plugin that along with a project's gradle.build file will bring into the project any dependencies the project needs, placing each dependency where the project expects the files to reside. Currently, it is working by placing them all in a /libs/ folder in the project, but that is not enough. What I'd like to be able to do is to specify in the gradle.build file where to put the dependency in the project.
Here is a simple example: I have a project that has been used for years as a component in other projects. It is a real pain to update all projects when that core component code has been updated... each project repository has to have the new files committed (using SVN, specifically). The files must reside in a particular directory so the ColdFusion framework (FW/1) correctly interacts with the code.
So what has been done is that core component is now in Artifactory and the gradle.build file pulls it down into the projects. That would be the end of the story if it was the only dependency, but there are others that need to be pulled down and the code expects those to be in a different directory than that one component. Each project will have different dependencies, and potentially different file structures (for example, our older apps are using the Fusebox framework). So the ability to control where a dependency ends up as specified in the gradle.build file is what I'm after.
This is what I was hoping to be able to do:
dependencies {
// exploded is a configuration that is added to this plugin
exploded('com.foo:bar:2.0-SNAPSHOT#zip') {
ext {
moveWhat = ['app']
moveWhere = 'assets'
}
}
exploded('com.foo2:bar2:1.0-SNAPSHOT#zip') {
ext {
moveWhat = ['*']
moveWhere = 'lib'
}
}
...
The hope was that I could pass directories/files into moveWhat that would then get placed into the directory specified by moveWhere, but I'm having trouble figuring out how to associate properties with each dependency. I'm having trouble figuring out if this is even possible.
Can anyone point me in the right direction?
I would suggest you use a separate task to extract what you need from the configuration. Something like this:
task copyFromExploded(type: Copy) {
into new File(project.buildDir, "assets")
from (configurations.exploded)
include "**/app"
}

How to make a GDSL file in a jar get picked up in another project in Intellij?

I have a project with a GDSL file that describes a DSL delegate like:
def ctx = context pathRegexp: ".*installer\\.groovy", scope: scriptScope()
contributor(ctx) {
delegatesTo(findClass("com.whatever.InstallerBase"))
}
I package this file up in the jar (just in the root of the jar) using maven.
In a separate project I have a maven dependency on my jar artifact containing the gdsl. However, my autocompletion doesn't work. It works fine with the sample scripts in the first project (with the GDSL).
Is there a step that I'm missing in order for the GDSL to be picked up? Do I need to place it in a special folder in the jar?
The problem was indeed what #PeterGromov indicated in the comment on the question:
ensure that the library jar is only attached as classes and not library source as well
both the source and library were configured and thus IDEA doesn't include it. I have opened a youtrack issue to fix this here:
https://youtrack.jetbrains.com/issue/IDEA-137411

Is there a way to prevent IntelliJ IDEA from compiling logback.groovy?

I have a groovy project in IntelliJ IDEA that uses logback.groovy. It's in src/main/resources so that it ends up in the classpath of the project, but IDEA compiles it into logback.class. Logback expects this to be in .groovy format, so this won't do. Is there a way to prevent this behavior? I just want logback.groovy in my classpath for running unit tests and webapp debugging.
IDEA 13 now supports new types of directory assignments under your content root: the relevant one for this question is "resources".
In previous versions, IDEA only supported marking directories as "sources" or "tests".
So the new correct answer is to mark src/main/resources directory as a resources folder of your content root. By marking the contents of a directory as "resources", you're telling IDEA that the contents are not source code but need to be accessible on the classpath at runtime.
[Added as a separate answer because the first one is still potentially useful if your file is stuck under your source tree for whatever reason - feel free to merge it in to the other answer if that's more appropriate.]
I guess /src/main/resources is marked in IDEA as a source root? That's pretty much explicitly telling IDEA "the stuff under this directory is source files".
You could try adding the file to /Settings/Project Settings/Compiler/Excludes - but that will probably mean that your file won't get copied onto your output path (and thus won't be on the runtime classpath so logback won't see it).
My personal solution is that my logback.groovy sits outside of my /src tree - I consider it to be configuration rather than a source/resource file. My config directory itself is then added to the runtime classpath directly via /Project Structure/Modules//Dependencies (marked as runtime scope).
My solution was to modify the artifact to explicitly include logback.groovy in the WEB-INF/classes directory. It isn't ideal since this file could only be referenced by the absolute path and not as a project file, so any suggestions are still welcome.
I put logback.groovy in src/main/resources and added it to Resources patterns in IDEA's Compiler settings (ctrl + alt + s; Compiler > Resource patterns). And it works :)

Resources