To date, I have always coded using a text editor, and compiling using CLI (Windows and Mac). This is the first time I've used an IDE, and I have chosen NetBeans. It is also the first time I have come across packages.
Would appreciate some guidance/direction on how to setup my project.
My project consists of:
- a Server app
- a Client app
- common objects
This is what I have done:
Create a Project
Under this project, I created three packages:
Server - source files specific only to my Server application
Client - source files specific only to my Client application
Common - common files shared by both Server and Client applications, such as RMISSLClientSocketFactory, remote interface and implementation, keystore files etc
Is this the right approach?
And also, what do I need to do to enable the Server all and Client app can call/access the classes in the Common package?
Many thanks in advance.
General convention would suggestion your top level package name should be the reverse of you companies web address (ie com.stackoverflow).
Now not everybody has a company (or web address), in these cases you want to choice something that will (as well as possible) uniquely identify you package (the purpose of packages is to provide name space, so you can have more the one class with the same name and be able to differentiate between them, amongst other things).
In may case I might choose to use mad.programmer for example...
The next level should identify the application or library (I personally use things like .core and .core.ui for my core libraries, but you can make you own choices)
At this point, you're basically free to group as you see fit.
Now, to the question at hand.
In your case, I would create three projects. One being for the server code, one being for the client code and one for you common classes (which would be shared between the server and client).
I would link the common project to your server and client projects (right click the Libraries node of the project (client and/or server) and select Add Project).
Personally, I would use the .client, .server, .common suffixes to you package names just to separate the code but the only really requirement is to provide your common library with it's own name space, separate from the server and client.
So long as you haven't changed any code that the sever and client rely-on to communicate (objects that might be passed between them at runtime), you can rebuild either project without affecting the other.
That's my take on it any way.
Related
I am considering switching my applications existing WFS/WMS "SDK" to GeoServer. However my application has a few special requirements.
I must remain in control full of the applications entry point (main(...)).
I cannot introduce any additional interfaces (such as the GeoServer GUI).
Essentially my application just needs an SDK which exposes our data over an HTTP "/wfs" path. We need to avoid any other interfaces or code being added or exposed. This is unfortunately an unavoidable requirement. Also, until now I have little experience in the GeoServer source code as we have been using a different Toolset. I am of course combing through the source, but am having trouble finding the right classes to get started.
In our existing SDK, I am able to programmatically create a Jetty server with a WFS Servlet assigned to our desired path. One class is provided during the Servlet initialisation which handles communication between our code, and the Servlet.
In order to get a similar setup using GeoServer, I am assuming:
I must add org.geoserver.gs-wfs to my pom.xml dependencies
I must run my own Jetty server in my Main function, and programmatically add the WFS module somehow
I do not yet know:
How to initialise and add the gs-wfs module to my own programatically created Jetty server
How to get a shared instance of the Catalog to add / remove the configured data
With specific focus on points 1 and 2 above, how do I initialise an instance of "just" the GeoServer WFS endpoint?
The path you're taking is too complicated (besides, there is no WFS servlet to start with)... the GeoServer war is the packaging of a modular application, with a selection of modules of common usage included in it.
If you want to remove the GUI you simply go into the packaged war file, and remove any jar that starts with "gs-web". Since you want full control, you probably want to remove also the administrative REST interface, thus remove also all jars starting with "gs-rest". That should get you close to an application that can start, and can run.
I say "close" because this operation is not commonly attempted, and there might be some unintended cross-module dependency preventing it to work.
Another possibility is to check-out GeoServer, get into src/web/ap (or clone it) and edit the pom.xml file, removing all dependencies you don't want... rebuild and you'll get a minimized war file with only the necessary jars.
GeoServer is a lot more complex than just a pick and mix bag of jars. If you want to create a single jar WFS server you will need to start with a copy of the specification and probably an understanding of how GeoTools (the underlying library of GeoServer) works, and about a year or two of development time.
Or you could read the GeoServer manual and turn off the GeoServer GUI. Then all you need to do is master the REST API to load data into it.
I am currently helping a small hosting company. There is no experience existing in regards to writing Java code.
They now have the order of a customer to host a complicated product using Tomcat, which needs some prelimanary work to be done beforehands. In detail, some Java Proxy classes need to be created using NetBeans (and Eclipse).
I think this is subject to be done by the software manufacturer. However when starting to work with this topic following a documentation of the manufacturer I see that i.e. when creating a WSDL the connect to an internal server (inclusing user name/password) is necessary.
So I wonder how to have this work to be done by the manufacturer without having access to our webserver? I.e. creating a WAR-file?
Usually, the developers should create a deployable artifact that - if the Tomcat itself is configured correctly - simply needs to be deployed and will run out of the box. That is the war file! So basically there is no need to access the hosting company server itself, neither to write any code in Eclipse/NetBeans to get the application up and running. If the customers say so, they either have a really weird code base there, or they simply do not know what they are talking about.
I have a server application and two Swing-based client applications. We're developing them in eclipse and there's a separate project for each.
Many classes are shared. For example, the my.server package has some classes for both the server and the clients while others are for the server only. Although I prefer to put them in the same package because they are closely related and some of them rely on package visibility, I don't want to distribute classes that an application does not need as not only would it bloat the file size, but also it would be a security risk.
At the moment, each of the server and the clients has the same jars, which is a mess. Ideally, I'd like to automatically create jars based on dependency as following.
Server:
server.jar: classes used by Server only
server-client1-common.jar: classes shared by Server and Client 1
server-client2-common.jar: classes shared by Server and Client 2
Client 1:
client1.jar: classes used by Client 1 only
server-client1-common.jar: classes shared by Server and Client 1
client-common.jar: classes shared by Client 1 and Client 2, but not Server
Client 2:
client2.jar: classes used by Client 2 only
server-client2-common.jar: classes shared by Server and Client 2
client-common.jar: classes shared by Client 1 and Client 2, but not Server
I realize that you can do this manually using ant, but it would be a maintenance disaster. Is there a tool that takes care of such dependency automatically?
What do you mean by "maintenance disaster"? If you create an ANT script, just run it and it will compile and pack the jars for you.
As a more robust alternative, you might use maven. For something more lightweight, the built-in eclipse export tool might work.
I cannot present you with a ready-to-go solution. Here's an idea though: create an annotation or a set of annotations like this:
#jarselector(types='server')
class ServerOnly {
...
}
#jarselector(types='server,client1')
class ServerAndClient {
...
}
Then create your own ant task by extending the jar task (or maven plugin) or write your own task, that takes this annotation and packages classes according to the annotation, which you would then be using as a filter.
You would only have to create the task once - I've done it in the past, it is less complicated than it sounds and the problem sounds big enough to warrant the effort.
Afterwards you have to annotate all your classes once (or depending on your implementation only those classes the clients need, or only those that are not shared by every jar etc.). Whoever sees a class can see immediately what it is used for. When creating a new class you can easily add the annotation.
I really don't think there is a ready made ant task or maven plugin that does this.
Alternatively - if you really cannot change your package structure - you could also use multiple source directories to keep the packages but split the files in different directories. Eclipse doesn't care how many source directories you use. You would then need to adapt your build tool just once for the source directories and could then sort the files that way.
One of the best practices regarding building applications is to have one jar per project.
Maven, for example, uses this as default. You can trick it to do otherwise, but it is better to join them instead of "fight" them.
http://maven.apache.org/guides/mini/guide-using-one-source-directory.html
http://www.sonatype.com/people/2010/01/how-to-create-two-jars-from-one-project-and-why-you-shouldnt/
So, in your case you should create 6 projects:
Server, Client1, Client2, ServerClient1Common, ServerClient2Common, ClientCommon
In order to select the classes needed, I don't think there is a tool, and probably you should know better what is the common functionality.
Create the Common projects, and add them to the build path - dependencies. Then start moving your classes into the Common project, leaving them in the same package.
For example, create ServerClient1Common project.
For Client1, go to Configure Build Path -> Projects. Add ServerClient1Common. Remove all references to Server Project.
For Server, go to Configure Build Path -> Projects. Add ServerClient1Common. Remove all references to Client1 Project.
You should now have a lot of missing classes/imports. Try to solve them one by one.
At the end, you should be able compile the 3 projects and to obtain the jars you mentioned.
PS: Other strategies (like one uber-project with different build targets, or 3 projects with entwined ant/maven builders) are messier. There is maybe one exception - another way of splitting the classes, but I do not know if it applies to you: client1.jar, client1-interface.jar, client2.jar, client2-interface.jar, server.jar, server-interface.jar. This way you could use 3 projects with each having two target jars. To run client2.jar you will need server-interface.jar
Have a separate Eclipse project for each JAR that you're going to create. Then set up the dependencies on the "Projects" tab of the Build Path, for each of the top level projects. So, the "server" project will have "server-client1-common" and "server-client2-common" listed as required projects. And so on.
I've seen this model used by a number of different organisations, and I've always thought that this was the "industry accepted" way of doing it. It just works!
I am developing a Spring (Java framework for server-side web-development)web application, which will respond to another client-side Java application(which uses socket communication) by a JSON object. At the same time, I'm working on both server-side and client-side Java applications.
The problem is that I have a bunch of files(say, a Json variable interfaces) that are being used at both projects. For now, I have duplicate copies of that interface, in different packages in the two projects. But this causes inconsistency, because I have to update the both files whenever I need to make a change in the interface.
Does anyone have a neat solution for this?
Thanks
You should treat your shared code at the package level and not the file level.
You should create a package of interface definitions that are used by both the client and server side of your architecture and whenever that package changes, both sides will have to change accordingly.
EDIT:
I wasn't explicit about it but zellus' suggestion about importing the common code as a jar is a good one.
You might create a separate project for your common JSON code. Using subversion, svn:externals allow a neat integration on the source level. Importing the common code as jar file is another approach.
If you're using maven, you could create a local maven project containing all the classes you might need in different projects and add this dependency to your pom.xml which requires these classes.
I have a Java project that has both server and client packages. In addition I have a library package.
I use eclipse and have put everything in a single Java project, each section server,client and library are in separate packages, the problem is that when I export, everything gets added to the Jar file.
So I suppose I need two different projects, client and server, but what about the shared library files? What do I do about them? Do I actually need three different projects? It will become a little unwieldy as everything is actually related and I would like to keep them together.
I use eclipse and have put everything
in a single java project, each section
server,client and library are in
separate packages, the problem is that
when I export, everything gets added
to the Jar file.
This is the part that intrigued me, why are you exporting something that has both the client and the server? From a client-server perspective they are going to be distributed separately.
Do I actually need three different
projects? It will become a little
unwieldy as everything is actually
related and I would like to keep them
together.
Thanks to how IDEs can now manage dependencies across projects/modules, I don't think it looks as bad as you picture it. For example you can work simultaneously on the server code, and use its classes and interfaces from your client code, and reference JARs produced by the server project.
I'd like also to add that a 'Project' isn't the broadest encapsulation of code either, there is still a 'Workspace' that can contain a number of related 'Projects'. Other IDEs go for other wordings like 'Module' instead of 'Project'.
Closing thoughts:
For the least impedance path, I think you should separate the client and the server parts into two projects, and do the same think for the shared library in case you are compiling it from source i.e, not a 3rd party JAR.
So in the end of the day you will have 3 'products' from the compilation process and distribute them where they belong, with the 'library' duplicated on both distribution sides.
You can have a separate project for your shared code, and create a library (i.e. jar file) for that. Then, your client and server projects can both use the shared library.
Even better, you can use this shared library for other projects in the future.
Note:
Eclipse is just going to compile the source files into their respective class files and put then in the bin folder, or wherever you have your output folder set for the project properties. It doesn't create a jar file by default.
If you want to create jar files, the best way is to use a tool like ant. Then you would be able to create whatever jars you need, and structure it however you like.
Here's a link for reference:
Create Multiple JARs from Eclipse Project
You can create the separate project for client and server side, the shared package can be attach in the class path definition.
... the problem is that when I export,
everything gets added to the Jar file.
Is that really a problem? Maybe the shared code is an asset rather than a liability. Perhaps you should optimize the developer issues before worrying about the deployment problems that, around here, we've decided aren't problems after all.
So I suppose I need two different
projects, client and server, but what
about the shared library files? What
do I do about them? Do I actually need
three different projects? It will
become a little unwieldy as everything
is actually related and I would like
to keep them together.
We have a similar situation here and chose to embrace the shared code. Everyone gets the same code and choses what mode and configuration they need to start up.
If you check out our large-ish system (a bit over 5000 classes), you get the code for the servers (two main flavors), the clients (another two types), shared content (third party jars, visual assets, etc.) and site specific material (configuration files, start-up scripts and example data).
The result is that, after one checkout, you have the complete package for all of our primary locations, build scripts and Netbeans and Eclipse launch configs. As a result, you can go from an empty machine (with just an IDE) to a working client-server combination in about five minutes.
As a result, double-click the server icon and you launch a server process, running the site-specific configuration. Double-click the client and you launch a client process that's ready to connect to the server you just made.
Punchline: don't make development and deployment harder on yourself unless there's a very good reason. In our case, it was simpler, cheaper and easier to maintain the situation where we gave every installation the exact same package.