Is it possible to modularize the app/models folder adding packages into it in play2.1 framework (java)?
Actually I have to put all of my classes (models) into app/models folder, otherwise play! framework can't find my classes on compilation time. I really don't like to have all of my classes into a single folder.
I did a research about play2 projects on github and most of them are simple and have all of their models into app/models with no packages into this folder as the samples bundled with the framework.
Do you add packages into app/models folder in your project? If so, do you have to configure something else?
Thanks for your time.
You can create as many packages in the models package as you want, and I consider this good practice. I.e. this is how my current structure looks like:
/models
/i18n
/forms
/roles
/utils
/users
The only thing that you must change is that you must use the fully qualified name as parameter in templates. (see this post)
Besides that, if you call static methods, you must also use the full name: #User.getUsername becomes #users.User.getUsername.
Related
I want to understand the packing methodology in real big projects.
Suppose we have a package com.abc.xyz, and for this, we really have a path like com/abc/xyz.
Is it possible to have multiple same package names in different directory structure like:
Directory path 1:
/home/user1/project/module1/src/java/com/abc/xyz
Directory path 2:
/home/user1/project/module2/src/java/com/abc/xyz
And finally when we create jar for the whole project, do we create jar with respect to com directory?
When some application uses import com.abc.xyz, how does it know which directory path's package it is referring to?
And finally, is there any good book/resource which gives guidelines about packaging, how to divide project into modules, package names etc.
One more thing, does a project have common package base name like in above case:
com.abc.xyz (e.g., org.apache.hadoop ).
Thanks,
Vipin
Packages created in different source directories are the same package, as far as the classloader is concerned. It also doesn't matter if the class files are in the same jar or different jars. The JVM does not discriminate based on where the source code came from.
(Of course if you have two jars loaded by different classloaders those are going to be treated differently.)
One case where you frequently have different source trees with the same package is when you have tests in a different directory (using the usual Maven convention where the code is under src/main/java and the tests are in src/test/java) but with the same package as the code that they exercise. These tests are able to exercise protected and package-private parts of the code under test, because they're in the same package as that code.
The path of directories inside the jar should start at the root of the package. (The topmost directory should be /, then one called com or org or whatever, etc.) Packages do form a tree-like structure, and when you put your code in a filesystem you end up having a hierarchy of packages, but the language itself doesn't recognize a concept of "subpackage" (except that packages that start with java are special and get special treatment by the classloader).
Organizing code into packages is done differently by different people. Some people like to organize their code by layer (putting all controllers in one package, all services in another package, all daos in still another package), some like to organize their code by feature.
Package-by-layer is the conventional way of organizing code, it seems to be the preferred practice in the Java community. One consequence of this is that when code implements a feature as a vertical slice at right angles to the package structure (as it may require a new controller endpoint, maybe a new service method, etc.), so closely-related bits of code for the same feature end up scattered across different directories. The Java Practices website makes an interesting case for package-by-feature:
Package By Feature Package-by-feature uses packages to reflect
the feature set. It tries to place all items related to a single
feature (and only that feature) into a single directory/package. This
results in packages with high cohesion and high modularity, and with
minimal coupling between packages. Items that work closely together
are placed next to each other. They aren't spread out all over the
application. It's also interesting to note that, in some cases,
deleting a feature can reduce to a single operation - deleting a
directory. (Deletion operations might be thought of as a good test for
maximum modularity: an item has maximum modularity only if it can be
deleted in a single operation.)
Here's an SO question asking about package by feature or layer.
Yes, you could make duplicate packages in separate directories, but I can't think of a good reason to do it. If the classes within the package have the same names you can certainly get namespace collisions. I am not sure what "module" means in this context but I'd recommend
com.abc.module1.xyz
com.abc.module2.xyz
instead. Those would be distinct packages to the classloader. You can still keep your /home/user1/project/module1/ directory structure up front, that doesn't matter.
From 2 modules you will have two seperate jar files: module1.jar and module2.jar. Both will be loaded into ClassLoader when application starts.
When some application uses import com.abc.xyz, how does it know which directory path's package it is referring to?
Classloader will handle that. http://www.javaworld.com/article/2077260/learn-java/the-basics-of-java-class-loaders.html
If you trying to develop multi module application i recommend you to check Maven tool:
http://maven.apache.org/
Why maven? What are the benefits?
For guidance for package organization you can just google 'java packages' phrase.
http://www.tutorialspoint.com/java/java_packages.htm
https://www.facebook.com/Niranthara-Jaya-JavaSocial-Media-Apps-Software-Project-Management-244119296136021/
This page is for people who wish to know how to work with real world Java projects. Send a message to this page and check out the articles.
I am building a tool from several different open source libraries. My buildpath is in the following order:
My first JAR file, stanford-corenlp-3.3.0.jar, contains a package called edu.stanford.nlp.process, which has the Morphology.class class.
My second JAR file, ark-tweet-nlp-0.3.2.jar, contains an identical package name (edu.stanford.nlp.process), and an identical class name Morphology.class.
In both JARS, inside their respective Morphology classes there exists a method called stem(). However, the constructors for these methods are different. I want to use the stem(String, String) method from my second JAR file, but since the import statement (import edu.stanford.nlp.process.Morphology;) does not specify which JAR to use, I get an error since it thinks the first JAR on the buildpath is the one I want to implement.
I don't want to change the order of my buildpath since it would throw off my other method calls.
How can I specify which JAR's Morphology class to use? Is there an import statement that specifies the JAR, along with the package.class?
EDIT: What about a way to combine my two JARs so that the two Morphology classes merge, giving me two methods with different constructors?
As several others pointed out above, it is possible to tweak Java's classloader mechanism to load classes from certain places… but this is not what you are looking for, believe me.
You hit a known problem. Instead of worrying how to tell Java to use a class from one JAR and not from the other, you should consider using a different version of ArkTweet.
Fetch the ArkTweet JAR from Maven Central. It does not contain Stanford classes.
When you notice that people package third-party classes in their JARs, I'd recommend pointing out to them that this is generally not a good idea and to encourage them to refrain from doing so. If a project provides a runnable fat-jar including all dependencies, that is fine. But, it should not be the only JAR they provide. A plain JAR or set of JARs without any third-party code should also be offered. In the rare cases that third-party code was modified and must be included, it should be done under the package namespace of the provider, not of the original third-party.
Finally, for real solutions to building modular Java applications and handling classloader isolation, check out one of the several OSGi implementations or project Jigsaw.
The default ClassLoader will only load one of the jars, ignoring the second one, so this can't be done out of the box. Maybe a custom ClassLoader can help.
For more info about ClassLoaders start from here.
Good luck!
EDIT: We are looking at some horrible packaging choices causing as side effect this Jar Hell here. The author of this "Ark Twitter" library decided it was a good idea to release a JAR artifact that includes a third party library (the Stanford NLP library). This leads to unnecessarily tight coupling between Ark Twitter and the specific version of the Stanford NLP library used by it. This is a very bad practice that should be discouraged in any case: this violates the whole idea about transitive dependencies.
EDIT (continued): One possible (and hopefully working) solution is to rebuild the Ark Twitter JAR so that it does not include the aforementioned library but only its own code (basically the cmu.arktweetnlp package only) and hoping that the version of NLP required by your project works with Ark Twitter. Ideally you should submit a pull request to the author of the library but in the meantime you can get away with un-jarring and re-jarring the existing JAR file.
EDIT 2: Looking at the JAR file again, it's much worse that I originally thought: ALL the dependencies are repackaged in the released JAR file. This is really the worst possible solution for releasing a library. Good luck.
I think your problem can be solved simply by using the lemma(String word, String tag) method in the current CoreNLP's Morphology class:
String word = ...;
String tag = ...;
String lemma = morphology.lemma(word, tag);
WordTag wt = new WordTag(lemma, tag);
When the class was revised a couple of years ago, the method you're looking for was deleted. The feeling was that with most of the Stanford NLP code moving to using CoreLabels, methods that return WordTag are less useful (though deleting all such methods is still a work in progress).
No there isn't. This is a weakness of Java, that cannot be simply solved. You should use only one of the libraries. Having both on the classpath will make java always select the first one.
This problem is named as Jar hell.
The order in the buildpath generally determines the order in which the classloader will search for the class. In general, though, you don't want duplicates of the same class in your build path--and it sure doesn't seem like ark-tweet-nlp-0.3.2.jar should have a edu.stanford package within it.
When you load a class, it's loaded at given address, and that address is then placed in the header of objects created from the class, so that (among other things) the methods in the class can be located.
So if you somehow load ClassA, with method abc(String), from zip file XYZ.zip, that loads into address 12345. Then (using a class loader trick) you load another ClassA, with method abc(String, String), from zip file ZYX.zip, and that loads into address 67890.
Now create an instance of the first ClassA. In its header will the class address 12345. If you could somehow attempt to invoke the method abc(String,String) on that class, that method would not be found in the class at 12345. (In actuality, you will not even be able to attempt the call, since the verifier will stop you because, to it, the two classes are entirely different and you're trying to use one where the other is called for, just as if their names were entirely different.)
At least on my machine when I put 2 Java class files on the same folder, without making them part of the same package, they already see one another, so from one file I can call a public class from the other file and vice-versa.
Questions:
Is this the general case or a coincidence that may not work on every platform?
If this is not a coincidence, I am guessing the purpose of packages is to allow you to organize your class files and make they share stuff, even if they are spread across different folders and paths. Is this correct or I am missing something?
If no package name is specified, the classes in the file go into a special unnamed package. And this is the same case for all files with no explicit package specification. Hence, they all fall into the special unnamed package, and exhibit the behavior that you are seeing.
You might want to go through this for a better understanding.
If they're in the same directory then they're in the same package, or are you copying .class files around after they've been written by the compiler?
Packages are a way of organising classes into a namespace. There are plenty of reasons to do this, the best bet is to start with the tutorial.
I sure it is general case, but it is bad approach.
You are right, but more general reason to use package is to separate namespaces, for example, you have to create Car class, but there are many people who want to use this classname, thats why you have to use package, for example: com.yourcompany.yourproject. In such case you can use your Car class from your package without implicitly defining package and you also can use other Car classes in such manner: new com.google.general.Car();
In the java rules, it is recommend to use domain name right-to-left for providing unique package name.
I am not so aware of the java project structure. I have few selenium tests which I want to write in java. So I have chosen eclipse as my editor. Here I wan to create a new java project with proper folder structure as I am planning to add few more java classes in future.
Please let me know how to create an idea java project in eclipse. I have seen people create something like com.org.project_name etc and then src , resources directories inside that.
I am not able to make any sense out of those. Please explain.
The software project management tool Apache Maven recommends, uses and expects a common directory layout that can be considered as best practise.
An overview can be found here: Introduction to the Standard Directory Layout
In Java you can create packages. Simply said packages are folders that contain classes.
The statement import java.net.Socket means: from the folder java/net import the class named Socket.
The statement package myApplication.util.SuperCounter means that the class SuperCounter can be found under myApplication/util folder.
Packages are an easy way to organize your work. Because in a big project you will have class name collisions (i.e. classes that use the same name). With packages you can avoid it.
Also Java supports default (private, public, protected). Default methods, attributes, classes can only be seen by elements in the same package!
Eclipse should create the proper folders for you...here is an example
http://www.wikihow.com/Create-a-New-Java-Project-in-Eclipse
If you want to have a Java Project then go to File -> New -> Java Project.
If its web application then, select Dynamic Web Project.
These will automatically create the required structures.
In Java you work in packages, which define the scope of your classes, and is basically the only thing you should really be concentrating on in the beginning. There's a good article on the subject here - http://docs.oracle.com/javase/tutorial/java/package/packages.html
I created a program in Java and I designed it so that methods that I want them to appear (getter methods) in the main, I can call them easily after initiate the class that holds these methods.
The question is that, I need to make this application (that holds the getter methods) to be like an API so that I can give my application for developers to use my functions (the getter methods) if they need them, and only what they need is to add this file (I think the API after is done shown as .jar file).
How can I make it so that I can make my code reusable with other application? It's similar to the .dll, I think.
Thanks a lot ;)
Create a JAR. Then include the JAR. Any classes in that JAR will be available. Just make sure you protect your code if you are giving out an API. Don't expose any methods / properties to the end user that shouldn't be used.
Edit: In response to your comment, make sure you don't include the source when you package the JAR. Only include the class files. That's the best you can really do.
To be useable as an API, your classes should:
Use a unique package (ideally following the convention, i.e. the reverse of a domain you own as prefix). This prevents naming conflicts
Have only those classes and methods public or protected that are intended to be used by others. This makes it easier to use.
Have extensive Javadoc comments.
Be available as a JAR file - ideally separate JARs for binary distribution, source code and javadoc files.
You need to package your application as a jar file. You can use ant jar task to create jar files or you can use the jar command.
For ant tasks look at this link.
For creating it manually look at this link.
Make sure you write and publish javadocs for all your public and protected classes and methods.
To create the jar:
jar cf <jar_name> <sources>
There are several ways you can expose your code. Creating a jar and distributing that may be the easiest as other developers will just have to include your jar. However, if you are talking about "anyone" accessing your code, a web service may make more sense as you can provide access to the data without providing all of the necessary code. You mention providing access to your getters - if you just create a class that has getters, the other developers can use them, but how are they going to be populated? If your application is self contained in that it gets the necessary data and provides the getters, that should work, but if you are talking about providing access to data from your running application, a web service makes more sense as your application can retrieve the data and provide access via publicly accessible methods.
You most likely want to create interfaces as well so developers can code against the interface and you can change the internal workings without impacting them. Any API that will be used by others should be extensively documented as well.
Well, depends on your IDE. I use Netbeans, so I just hit build project, and viola! A jar file is created in my directory specified. Now, that's just for compiling. All anyone has to do is download your .jar file, and if in Netbeans, right click libraries, add jar/folder, and select the downloaded file.
You can also consider:
Include some samples that demonstrate how to use your library
Build your jar using Apache Maven
Put your jar in a public maven repository
Publish a new version of your library as you find/fix bugs
If you want to hide your implementation, you can pack your jar with obfuscation, so that if someone decompiles your classes, the code will be difficult to read