how to include all subdirectories as gradle modules? - java

I'm going to have a lot of submodules in my main project directory x, like x/module1, x/module2...
can i avoid manually adding every single module into settings.gradle? can i somehow script it to find all the subdirectories and add them automatically?

As cricket_007 already mentioned, Gradle is based on the Groovy programming language (which is, like Java, executed in the JVM) and the settings.gradle file is nothing more but a Groovy script.
Whenever you use include 'project', the include method of a Settings instance is called, so for your goal, you could simply create a loop which iterates over all folders and calls include for each of them.
A more 'groovyesque' approach would be the usage of a closure for each subdirectory, provided by the Groovy SDK extension for the File class:
file('.').eachDir { sub ->
include sub.name
}
There are multiple ways to solve your problem, e.g. since the include method accepts an array of project path strings, you could also aggregate all required paths first and pass them all together. Simply get familiar with the Gradle docs and decide on your own, what solution suits your case the best.

Related

How the flavor-specific variants are working?

If you need flavor you should go to build gradle and add the flavors that you need
Like this
productFlavors {
mock {
applicationIdSuffix = ".mock"
}
prod {}
}
and then you need to create corresponding dir like this /src/prod/java/
How I thought it should work, according to build variant that was choosen for example prodDebug androidStudio will take as a base main source and substitute coresponding classes from dir according to choosen build variant.
But then I found this snippet which said next
Files in the flavor-specific folders do not replace files in the main source set. Trying to do that will result in a duplicate class exception. This is a common misconception because it's how resources are merged.
Ok, so with basic configuration with flavors, you have two kinds of source sets:
main source set
flavor-specific source sets, like your mock and prod
With standard buildTypes configuration (debug and release), this gives you the following build variants (combinations of build types and product flavors):
mockDebug
mockRelease
prodDebug
prodRelease
Each one of them uses every source set that corresponds with flavor/type name and the main set, so for example, the prodRelease will use all of the following source sets at once:
/src/main
/src/prod
/src/release
Effectively, the build system will 'merge' all of these into one source set, and that means if there are classes with the same path and name in these sets, a name clash occurs and compiler will fail.
The way to use source sets correctly is to omit the class that you need to be different for each set from the main set, but instead provide it with all the sets for each flavor / each buildType, for example:
main set has class A.java that references class B.java. B.java is omitted from main set.
Different B.java files are included in mock and prod sets (of course, don't need to be different, but need to provide the same interface, preferably with interface included in main set).
Compiler uses B.java from the set that is being used by the current configuration - build variant, so either the mock or the prod one.
Yay! Now you have two functionally different product flavors.
This behavior doesn't limit to classes, you can use flavor or type specific resources, AndroidManifest.xml files and just about anything that goes into the source dir.
Tip: In Android Studio you can see in the 'project files' section which files will be chosen to compile for a specific variant. To switch build variants, hit Cmd+Shift+A (mac keymap) and search for Build Variants phrase. It usually shows also on the left bottom side of the Android Studio window.
The code from the main source set will always make it into the APK. The source files in other source sets will only be merged if the correct build variant is used. For example, you can create two files:
src/mock/java/yourpackage/MyClass.java
src/prod/java/yourpackage/MyClass.java
Depending on whether you're building prod or mock variant, one of those classes will be compiled and packaged with the APK. Same works for debug and release: you can have code and resources that are only packaged into debug or release versions of the app.

Maven-war-plugin - remove files

I am developing maven plagin that obfuscates js files. It does the following -:
takes *.js files from target,
obfuscates them using google closure,
creates *.min.js files in target,
if it's necessary removes sources (unobfuscated files) from target.
In order to get point between package phase and prepare-package phase I use the following solution: https://stackoverflow.com/a/27566620/2022068
Everything is ok. Plugin is ready. However I have the following problem - if I remove source file, maven-war-plugin copies it again. Maybe it has some mechanism of checking - I don't know. The only thing that I can do now is to delete and create empty file. Than the source file exists but it's empty.
My qeustion - can I somehow remove files from target finally, forever...?
You probably need to teach this to the maven-war-plugin. I have no example that does the same thing but there are packageExcludes (see: http://maven.apache.org/plugins/maven-war-plugin/examples/including-excluding-files-from-war.html) which seems not exactly what you need but also warSourceExcludes: http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html#warSourceExcludes
The war plugin has its own mechanism of copying files (aside from the resources plugin). That may be the issue here. There are some examples on filtering as well: http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html
Maybe treating the files you don't want to see as excludes will work (if warSourceExcludes is something different than what you plan to do).

Load files dynamically in multiple environments

so I am in the process of making a small application.
Right now, the project works fine. I am running it through an IDE. The problem comes about when trying to run the project as a jar - which is the end result. Right now, it fails to properly load the required files (classes and simple ASCII files).
The method I am using is one based off of:
final Enumeration<URL> paths = CLASS_LOADER.getResources("");
Where CLASS_LOADER is an instance of class.getClassLoader().
This works great when not inside a jar. Inside a jar though, it seems to fail horribly. For example, in the code above, paths would be empty.
I am assuming that the fault is that the files are all within a jar - the same jar to be precise.
The class path for the manifest file is blank at the moment.
If it helps, I have two tasks that require loading files.
I need to create a list of all files that are a subclass of
another class.
I need to load a list of language files (all of
which are in the same directory).
If you need anything else to help debug this problem or provide a solution - let me know. Thanks for reading this!
For ClassLoader.getResources() to work you need to feed a path relative to the jar root. If you want to search the jar then ClassLoader public API won't help you. You have to use custom code based on java.util.jar.JarFile, like the one here.

How to make IntellijIDEA ignore work-in-progress class files?

When I'm working in IntellijIDEA how do I tell it to ignore a class file that may have problems and I want to leave dormant for a while?
It will throw errors when I compile whatever class I am working on until I fix the first "dormant" class.
I have tried adding my class to a bogus package but Intellij doesn't like that either because the path doesn't match.
Settings | Compiler | Excludes, add your WIP files there:
You could use Refactor -> Rename File..., and change the file extension.
That is set at the inspection level
Configure Current File Analysis CTRL + SHIFT + ALT + H
I have profiles with differing inspection levels setup loosely based on the phase of my project builds ... I'd suggest taking a look at Customizing Inspection Profiles.
To ignore specific files during compilation you can add files individually or recursively in via the project settings panel ...
Configure Compiler Analysis CTRL + ALT + S :: Compiler => Validation
A bit late, still
If all your files are in the same package, then right-click on the package in the Project tool window and pick "Mark directory as -> Excluded".
All the classes inside the package won't be compiled. You can cancel exclusion any time you want the same way.
Usually, only the classes that are used in the application are actually compiled.
In your case, I would guess that it's only broken unit tests that hinder the compilation (as opposed to any other Java classes in the /main folder).
The reason is this: When running all unit tests in a package or source folder, IntelliJ searches and includes all the files that appear like unit tests by default: those with Test or Suite in the class name, but also those annotated with #Test or #Suite.
So the easiest way to exclude your test is to create a third source folder, call it /ignore, and not mark it as a source folder in IntelliJ. You can then drop any file you don't want to include in your compilation there temporarily, and drag it back to its original folder when you want to continue working on it. Beware, though: You will get only limited tool support if you open and edit the file within an unmarked source folder, so it should really be used for "parking" only.
You could also change the file extension, as the other answer suggests, but then IntelliJ will also change its handling of the file in other respects, not just during compilation.
Also, if you're using JUnit 4, you can always annotate any single test method, or the entire test class, with #Ignore, and it will be skipped during the test run. This requires the class to be formally correct, though, i.e.: no compile time errors.
P.S: You need to actually move the test to a different folder, if you really want the package to change - not just edit the package declaration. Otherwise, a non-matching declaration will also be considered an error.

Eclipse plugin - Class object

I am creating an eclipse plugin, and I need Class object of selected file, not IType. Is it possible, and how is the best way to do it?
Edit: when I think about it, the best way is to add it like run as (like junit, profiler, or other plugins are doing). I suppose they must have access to Class (if X is class in question), because they are running it's functions. So how to create plugin that has "run as " action, and get live object?
In an eclipse plugin, you will, for instance, get the selected file through an IAction.
(it represents the non-UI side of a command which can be triggered by the end user. Actions are typically associated with buttons, menu items, and items in tool bars.)
From there:
IResource selectedResource = ResourceUtils.getSelectedResource();
IResource The workspace analog of file system files and directories. There are exactly four types of resource: files, folders, projects and the workspace root.
From its type, you can cast it into an IFile, which gives you acces to its full path (getFullPath())
Eclipse uses an abstract representation of the object being selected, be it a file (IResource) or be it a Java Type (IJavaType). As it is not required for a source file to be compiled (e.g. disabling auto build), there does not necessarily be a .class file or a Class object for the code being edited. Hence, there is no correct way to get a "Class" object from the a selection in the user interface.
However, as yesterday mentions, you could rely on the fact that the Eclipse builder mechanism will always compile the source files immediately and thus a .class file exists. To reach to this .class file at runtime, you would need to create a dynamic class loader for the project or start a runtime VM. I tried that and it does work, but it is a very unstable approach and can lead to various hard to trace failures.
The classname of an IType "curIType" can be retrieved through
curIType.getFullyQualifiedName()
That's the simple part. But then you have the problem, that this class does not have to be in the classloader of your plugin (if it's a class of one of the userprojects, it's seldom part of your classloader). So calling Class.forName(classname) won't do any good.
I had a similar case and did (in a first attempt) solve it by creating an own thread with an own classloader, which included all libraries of the current classloader and all libraries of the type's project. That's neither a short code nor a simple one and I've already refactored it. It's much simpler to get all information out of the IType and not using the classes anywhere in the plugincode.

Categories

Resources