System and method for run time dependency resolution

A system and method of run time dependency resolution includes loading one or more dependency descriptors from an archive, determining that a class is to be loaded at run-time, selecting a first dependency descriptor from the one or more dependency descriptors based on information associated with the class, requesting the class from a dependency repository based on information associated with the class and information associated with the first dependency descriptor, receiving the class from the dependency repository, and loading the class. In some examples, the system and method further include determining a package for the dependency repository, loading the package, extracting a class file from the package, splitting the class file into one or more fragments, tagging each of the one or more fragments with information associated with the class file and the package, and transmitting each of the one or more tagged fragments to the dependency repository.

BACKGROUND

The present disclosure relates generally to computing systems, and more particularly to run time dependency resolution.

As the value and use of information continues to increase, individuals and businesses seek additional ways to process and store information. One option is a computing system. Computing systems may vary in complexity from a single processor operating in relative isolation to large networks of interconnected processors. The interconnected processors may be in close proximity to each other or separated by great distances both physically and as distance is measured in computer networking terms. The interconnected processors may also work together in a closely cooperative fashion or in a loose weakly coupled fashion. Because technology and processing needs and requirements may vary between different applications, the structure and arrangement of the computing system may vary significantly between two different computing systems. The flexibility in computing systems allows them to be configured for both specific users, specific uses, or for more general purposes. Computing system may also include a variety of hardware and software components that may be configured to process, store, and communicate information based on the needs of the users and the applications.

Computing systems generally rely on one or more software components to deliver the services and information required by users and other systems. Software components typically work in cooperation with other software components and in many cases depend on the presence of these other software components in order to function properly. This reliance may often be managed by identifying and tracking the dependencies of one software component on others. As software components become increasingly more portable and flexible and are required to operate on different types of computing platforms, the handling of dependencies may become more complex as each computing platform may create different dependencies for the software components.

Accordingly, it would be desirable to provide improved dependency handling methods and systems for software components.

SUMMARY

According to one embodiment, a method of run-time dependency resolution includes loading one or more dependency descriptors from an archive, determining that a class is to be loaded at run-time, selecting a first dependency descriptor from the one or more dependency descriptors based on information associated with the class, requesting the class from a dependency repository based on information associated with the class and information associated with the first dependency descriptor, receiving the class from the dependency repository, and loading the class.

According to another embodiment, a non-transitory machine-readable medium comprising a first plurality of machine-readable instructions which when executed by one or more processors associated with one or more computing systems are adapted to cause the one or more processors to perform a method including loading one or more dependency descriptors from an archive, determining that a class is to be loaded at run-time, selecting a first dependency descriptor from the one or more dependency descriptors based on information associated with the class, requesting the class from a dependency repository based on information associated with the class and information associated with the first dependency descriptor, receiving the class from the dependency repository, and loading the class.

According to yet another embodiment, a system for management of dependencies includes a deployment platform including one or more processors and memory storing an archive and a dependency cluster including a plurality of dependency nodes. The one or more processors are running an augmented Java virtual machine (AJVM) including a class loader. The class loader loads a class at run-time as requested by the AJVM by selecting a dependency descriptor for the class based on information associated with the class, requesting the class from a first dependency node selected from the plurality of dependency nodes, and receiving the class from the first dependency node.

DETAILED DESCRIPTION

In the early days of computing, software developers often created software components or software projects entirely by themselves. As the complexity of software projects increased, it often became undesirable and inefficient to create all the elements of these software projects. Instead, software developers often rely on software libraries and packages to provide many features and elements of software projects. Each of these software libraries and packages often, themselves, rely on other software libraries and packages. Thus, in order to build or use a software project, the software developers and end users also need to have access to the relied upon software libraries and packages. This reliance is often formalized using one or more dependencies. The dependencies may be used by the build and/or target system to identify and/or locate the depended upon software libraries and packages so that they may be used by the software project.

FIG. 1Ais a simplified diagram of a dependency descriptor list100according to some examples. As shown inFIG. 1A, the dependency descriptor list100may be represented in tabular form. Although the dependency descriptor list100is shown in tabular form, any suitable format may be used including extensible markup language (XML), comma separated values (CSV), and the like. In the table ofFIG. 1A, each dependency descriptor in the dependency descriptor list100includes a package identifier or ID110and a version120. Package ID110may be used to identify a package or a library on which a dependency exists. In some examples, package ID110should be sufficiently descriptive to identify the package or library. Because many packages and libraries come in different versions, version120may also be used to uniquely identify a version of a dependency from among many possible versions. The dependency descriptor list100is shown with two representative dependencies131and132, although any number of dependencies may be included in dependency descriptor list100. Dependency131describes a dependency on version 4.0 of junit. Dependency132describes a dependency on version 1.1 of a package with a package ID of com.ourco.myproj.

FIG. 1Bis a simplified diagram of a dependency descriptor list150according to some examples. As shown inFIG. 1B, the dependency descriptor list150may be represented in tabular form. Although the dependency descriptor list150is shown in tabular form, any suitable format may be used including XML, CSV, and the like. In the table ofFIG. 1B, each dependency descriptor in the dependency descriptor list150includes a group ID160, an artifact ID170, and a version180. Collectively group ID160and artifact ID170may be used to identify a package or a library on which a dependency exists. In some examples, the combination of group ID160and artifact ID170should be sufficiently descriptive to identify the package or library. Because many packages and libraries come in different versions, version180may also be used to uniquely identify a version of a dependency from among many possible versions. The dependency descriptor list150is shown with two representative dependencies191and192, although any number of dependencies may be included in dependency descriptor list150. Dependency191describes a dependency on version 4.0 of junit, which may be identified using a group ID of junit, an artifact ID of junit, and a version of 4.0. Dependency192describes a dependency on version 1.1 of a package with a package ID of com.ourco.myproj, which may be represented by a group ID of com.ourco.myproj, an artifact ID of my_project, and a version of 1.1. In some examples, the dependency descriptors in the dependency descriptor list150may be consistent with dependency descriptors used with Maven, a build tool.

FIG. 2is a simplified diagram of a method200of building a software component using dependency descriptors according to some examples. As shown inFIG. 2, the method200includes a process210for compiling a project, a process220for loading dependency descriptors, a process230for loading dependencies from a repository, and a process240for adding the dependencies to an archive. According to certain examples, the method200of building a software component using dependency descriptors can be performed using variations among the processes210-240as would be recognized by one of ordinary skill in the art. In some examples, one or more of the processes210-240of method200may be implemented, at least in part, in the form of executable code stored on non-transient, tangible, machine readable media that when run by one or more processors (e.g., one or more processors in a computer workstation) may cause the one or more processors to perform one or more of the processes210-240.

At the process210, a project is compiled. Once software for a project has been written, each source code file in the project may be compiled. During the compilation of each source code file, a compiler typically needs to find a description of each object and/or function referenced and/or used in the source code file. Many of these objects and functions are often described in other packages and/or software libraries. Although many techniques may be used to aid the compiler in finding the descriptions, in some examples, the descriptions may be found through use of dependency descriptors and dependency repositories.

At the process220, dependency descriptors are loaded. During the compilation of process210and during other processes of build method200, each of the dependencies for the project may be identified and resolved. When the dependencies are formalized using dependency descriptors, the dependency descriptors may be loaded by the build tool. In some examples, the dependency descriptors may be included in a build file. In some examples, the build file may be a Maven project object model. As each dependency descriptor is loaded, a corresponding package and version may be determined. In some examples, the dependency descriptors may be consistent with the dependencies descriptors ofFIG. 1Aand/orFIG. 1B.

At the process230, the dependencies are loaded from a repository. To facilitate use of dependencies and dependency descriptors, the dependencies may be stored in a repository. In some examples, the repository may be stored in files local to a build workstation. In some examples, the repository may be hosted by a server. In some examples, the repository may be accessible using a network. In some examples, the repository may include multiple repositories. Using the package and version determined during process220, each of the dependencies is loaded from the repository. Once loaded, the dependencies may be used by the compiler and during other build processes.

At the process240, the dependencies are added to an archive. While only the description of each object and/or function is used by the compiler, a definition of each object and/or function may also be used during execution of the project on a target system. In some examples, the definition of each object and/or function may include compiled code for that object and/or function. In some examples, the compiled code may be a Java class file. In some examples, because it is not always known whether every target system for the project includes the definitions, the definitions for each dependency may be added to the archive used to distribute the project. In some examples, the definitions of some dependencies may be known to be present on the target system and may be omitted from the archive. In some examples, the archive may be a Java archive (JAR) file. In some examples, the archive may be a web archive (WAR) file. In some examples, the archive may be an enterprise archive (EAR) file.

According to some examples, adding each of the dependencies to the archive may not be very efficient. In some examples, adding each of the dependencies to the archive may result in large archive files. In some examples, the large archive files may use large amounts of storage space (e.g., on disk) and/or use large amounts of bandwidth to distribute. In some examples, each target system may already include copies of one or more of the dependencies added to the archive. In some examples, all of the dependencies may be added to the archive even though some target systems already store copies of one or more of the dependencies. In some examples, this may result in archives that are generally larger than many target systems need. In some examples, this may result in duplicate copies of the same dependency on the target systems, further consuming resources of those target systems. In some examples, different target systems may use different versions and/or variations of some dependencies. In some examples, this may result in different archives for each target system, each using resources of the build workstation. Accordingly, it would be desirable to load the dependencies at run time rather than assembling them at build time in the archive.

FIG. 3is a simplified diagram of a run time dependency resolution system300according to some examples. As shown inFIG. 3, system300includes a deployment platform310. Deployment platform310is the target system on which a software project is intended to be executed. In some examples, deployment platform may be a standalone workstation, a cluster, a production server, within a virtual machine, and/or the like. Deployment platform310includes a processor312and memory314. Processor312is coupled to memory314. In some examples, processor312may control operation and/or execution of software packages on deployment platform310. Although only one processor312is shown, deployment platform310may include multiple processors. Memory314may include one or more types of machine readable media. Some common forms of machine readable media may include floppy disk, flexible disk, hard disk, magnetic tape, any other magnetic medium, CD-ROM, any other optical medium, punch cards, paper tape, any other physical medium with patterns of holes, RAM, PROM, EPROM, FLASH-EPROM, any other memory chip or cartridge, and/or any other medium from which a processor or computer is adapted to read.

Memory314may further be used to store an augmented Java virtual machine (AJVM)320and an archive file330. AJVM320is a virtual machine capable of executing complied Java code. In some examples, AJVM320may be a dependency augmented JVM. AJVM320includes several components for managing, loading, and executing Java projects. The components of the AJVM320include a class loader325. Class loader325is used to load any classes that are used while a Java project executes. Archive file330may be an archive file used to distribute a Java project. In some examples, archive file330may be a JAR, a WAR, an EAR file, and/or the like. In contrast to the archive created during process240, archive file330may include one or more dependency descriptors335. In some examples, the dependency descriptors335may be included in the archive file330instead of the dependencies themselves. In some examples, the dependency descriptors335may be included in a dependency file stored in the archive file330. In some examples, the dependency file may be stored in the META-INF and/or a similar metadata directory of the archive file330. In some examples, the dependency descriptors335may be consistent with the dependency descriptors ofFIG. 1Aand/orFIG. 1B. In some examples, this may reduce a size of archive file330. In some examples, this may reduce a number of versions of archive file330used to support multiple deployment platforms.

In some examples, inclusion of the dependency descriptors335in archive file330may support run time dependency resolution by class loader325and AJVM320. In some examples, the dependency descriptors335may be used by class loader325to load only those dependencies that are actually used during execution of the Java project in archive file330. In some examples, the dependency descriptors335may be used by class loader325to load dependencies from a location other than archive file330and/or memory314. In some examples, class loader325may load the dependencies from a dependency repository.

As further shown inFIG. 3, deployment platform310is coupled through a network340to dependency cluster350. Network340may be any network including a local area network (LAN), a data center network, a wide area network (WAN), an autonomous system, an internet, and/or the like. Dependency cluster350is used to store a dependency archive to be used by class loader325. Dependency cluster350includes one or more dependency nodes, including dependency nodes360and370. Although only two dependency nodes are shown in dependency cluster350, any number of dependency nodes may be used. In some examples, although dependency cluster350is shown coupled to deployment platform310using network340, some portion of dependency cluster350may also be included in deployment platform310.

Dependency node360includes a control unit362and memory364. Control unit362is coupled to memory364and may control the operation of dependency node360. In some examples, control unit362may be used to respond to requests for dependencies made from a class loader such as class loader325. In some examples, control unit362may include one or more processors. In some examples, memory364may be used to store copies of some or all class files associated with a dependency. In some examples, memory364may store only portions of any given class file. Memory364may include one or more types of machine readable media. Some common forms of machine readable media may include floppy disk, flexible disk, hard disk, magnetic tape, any other magnetic medium, CD-ROM, any other optical medium, punch cards, paper tape, any other physical medium with patterns of holes, RAM, PROM, EPROM, FLASH-EPROM, any other memory chip or cartridge, and/or any other medium from which a processor or computer is adapted to read.

Similarly, dependency node370includes a control unit372and memory374. Control unit372is coupled to memory374and may control the operation of dependency node370. In some examples, control unit372may be used to respond to requests for dependencies made from a class loader such as class loader325. In some examples, control unit372may include one or more processors. In some examples, memory374may be used to store copies of some or all class files associated with a dependency. In some examples, memory374may store only portions of any given class file. In some examples, memory374may store portions of a class file that overlap with portions stored in memory364. Memory374may include one or more types of machine readable media. Some common forms of machine readable media may include floppy disk, flexible disk, hard disk, magnetic tape, any other magnetic medium, CD-ROM, any other optical medium, punch cards, paper tape, any other physical medium with patterns of holes, RAM, PROM, EPROM, FLASH-EPROM, any other memory chip or cartridge, and/or any other medium from which a processor or computer is adapted to read.

Dependency cluster350further includes a cluster network380. Cluster network380may be used to couple together each of the dependency nodes360,370in dependency cluster350. In some examples, cluster network380may be partially and/or fully included in network340. In some examples, cluster network380may form a peer-to-peer network between the dependency nodes360,370. In some examples, the peer-to-peer network may permit the dependency nodes360,370to cooperate in responding to a dependency request for a class file. In some examples, the dependency nodes360,370may cooperate in responding to the dependency request for the class file because each dependency node360,370only stores a portion of the requested class file.

FIG. 4is a simplified diagram of a method400of populating a dependency cluster according to some examples. As shown inFIG. 4, the method400includes a process410for determining packages for a dependency cluster, a process420for loading the packages, a process430for extracting classes from the packages, a process440for splitting the classes into fragments, a process450for tagging the fragments, and a process460for storing the fragments to dependency nodes. According to certain examples, the method400of populating a dependency cluster can be performed using variations among the processes410-460as would be recognized by one of ordinary skill in the art. In some examples, one or more of the processes410-460of method400may be implemented, at least in part, in the form of executable code stored on non-transient, tangible, machine readable media that when run by one or more processors (e.g., one or more processors in a computer workstation and/or in control unit362and/or372) may cause the one or more processors to perform one or more of the processes410-460.

At the process410, packages for a dependency cluster are determined. In order to support run time dependency resolution, a dependency cluster may be populated with one or more dependencies. In some examples, the dependency cluster may be the dependency cluster350. In some examples, the one or more dependencies are associated with one or more packages. In some examples, the one or more packages are determined based on dependency descriptors included in a build file (e.g., the build file used during process220). In some examples, when the dependency descriptors are included in the build file, method400may be part of a build process (e.g., as an enhancement to the build process of method200). In some examples, the one or more packages are determined based on dependencies stored in an existing dependency archive. In some examples, when the dependencies are stored in an existing dependency archive, method400may be part of a mirroring process for the existing dependency archive.

At the process420, the packages are loaded. Each of the packages determined during process410are loaded. In some examples, the packages are loaded from local memory, such as a disk drive. In some examples, the packages are loaded from a dependency archive, such as the dependency archive from process410.

At the process430, classes are extracted from the packages. Most packages include one or more classes. In some examples, each class may be stored in a class file. Each of the classes in each of the packages are extracted from respective packages for further processing.

At the process440, the classes are split into fragments. Each of the classes may be split into smaller more manageable units called fragments, because each class varies in size. In some examples, each fragment includes a fixed number of bytes from a respective class file. In some examples, when each fragment is 1 k byte in size and a class file includes 10.4 kbytes, the class file may be split into 11 fragments. In some examples, a last fragment from a class may be smaller than the other fragments. In some examples, each fragment may be identified by a starting byte within the class file. In some examples, when each fragment is 1 k byte in size, the starting bytes may be 0, 1024, 2048, etc. In some examples, each fragment may be identified by a fragment number indicating an ordinal position of the respective fragment. In some examples, when each fragment is 1 k byte in size, a fragment with fragment number 0 may include bytes 0-1023 and a fragment with fragment number 3 may include bytes 3072-4095. In some examples, other strategies may be used to split each class into fragments.

At the process450, the fragments are tagged. After each fragment is created, it is tagged with a tag so that it may be identified later. Each tag may include a package for the class from which the corresponding fragment was split during process440. Each tag may also include the dependency descriptor associated with the package from which the class was extracted during process430. Each tag may also include a starting byte and/or a fragment number corresponding to the fragment. In some examples, the tag may further include a total size of the corresponding class and/or a total number of fragments for the corresponding class. In some examples, the tag may further include a validation field for the corresponding class. In some examples, the validation field may include a checksum, a CRC value, an MD5 value, and/or the like that may support validation of a class file assembled from corresponding fragments. In some examples, only some of the tags for a class file may include the total size, the total number of fragments, and/or the validation field.

At the process460, the fragments are stored to dependency nodes. Each of the fragments from process440and their corresponding tags from process450are transmitted to one or more dependency nodes (e.g., dependency nodes360and/or370) in the dependency cluster for storage. In some examples, a number of copies of each fragment and corresponding tag stored in the dependency nodes may be based on a replication factor. In some examples, the replication factor may indicate the number of dependency nodes into which a copy of each fragment and corresponding tag may be stored. In some examples, when the replication factor is four, a copy of each fragment and corresponding tag may be stored in four separate dependency nodes. In some examples, the dependency nodes chosen for each fragment and corresponding tag may be selected based on a hashing mechanism. In some examples, the dependency nodes chosen for each fragment and corresponding tag may be selected randomly. In some examples, it is possible that no dependency node may store all the fragments for a particular class. In some examples, it is possible that a particular dependency node may not store any fragments for a particular class. In some examples, duplication of fragments among the dependency nodes may support high availability of dependencies from the dependency cluster. If some examples, when a replication factor of N is used, at least N dependency nodes may have to fail in order for the dependency cluster to be unable to provide a class when requested. In some examples, duplication of fragments among the dependency nodes may support load balancing among the dependency nodes because many dependency nodes are able to supply any given fragment. In some examples, this allows less busy dependency nodes to respond to a request for a fragment without have to wait on a dependency node that is busier.

FIG. 5is a simplified diagram of a method500of run time dependency resolution according to some examples. As shown inFIG. 5, the method500includes a process510for deploying an archive, a process520for loading dependency descriptors, a process530for beginning execution, and a process540for loading classes on demand. According to certain examples, the method500of run time dependency resolution can be performed using variations among the processes510-540as would be recognized by one of ordinary skill in the art. In some examples, one or more of the processes510-540of method500may be implemented, at least in part, in the form of executable code stored on non-transient, tangible, machine readable media that when run by one or more processors (e.g., processor312in deployment platform310) may cause the one or more processors to perform one or more of the processes510-540.

At the process510, an archive is deployed. The archive is deployed on a deployment platform such as the deployment platform310. In some examples, the archive is an archive file such as the archive file335. In some examples, the archive may be deployed for on-demand execution when a server and/or an augmented Java virtual machine (AJVM), such as the AJVM320, is started on the deployment platform. In some examples, the archive may be deployed when the archive is selected for execution. In some examples, the archive may be deployed when it is sent to the deployment platform. In some examples, the archive may deployed by extracting contents of the archive file and providing the contents to the AJVM.

At the process520, dependency descriptors are loaded. During and/or after the archive is deployed during process510, the dependency descriptors associated with the archive are loaded. In some examples, the dependency descriptors may be loaded by the AJVM. In some examples, the dependency descriptors may be loaded from a dependency file. In some examples, the dependency file may be store in the META-INF and/or a similar metadata directory of the archive file. In some examples, the dependency descriptors may be consistent with the dependency descriptors ofFIG. 1Aand/orFIG. 1B. In some examples, the dependency descriptors may be the dependency descriptors335.

At the process530, execution begins. Execution of the project in the archive begins in the AJVM. Execution may continue, subject to input/output and other run-time conditions, until an object and/or a file associated with a class that is not loaded is to be executed.

At the process540, classes are loaded on demand. Using a class loader, such as the class loader325, the AJVM requests that classes that are to be executed are loaded into main memory where the classes may be executed. In the AJVM this is typically handled in an on-demand fashion. Thus, classes are only loaded when necessary to limit an amount of main memory used by the project as it executes. In some examples, when the class to be loaded is already available in the main memory, the class loader may not be needed for that class. In some examples, when the class to be loaded is already available on the deployment platform (e.g., on a disk drive), the class loader loads the class to the main memory. In some examples, when the class to be loaded is not available on the deployment platform, the class may be located using a corresponding dependency descriptor and requested from a dependency respository.

FIG. 6is a simplified diagram of the process540for loading a class from a dependency cluster according to some examples. As shown inFIG. 6, the process540includes a process610for searching dependency descriptors for a class, a process620for determining information for the class, a process630for requesting the class from a dependency cluster, and a process640for receiving the class from the dependency cluster. According to certain examples, the process540for loading a class from a dependency cluster can be performed using variations among the processes610-640as would be recognized by one of ordinary skill in the art. In some examples, one or more of the processes610-640of process540may be implemented, at least in part, in the form of executable code stored on non-transient, tangible, machine readable media that when run by one or more processors (e.g., processor312in deployment platform310) may cause the one or more processors to perform one or more of the processes610-640.

At the process610, dependency descriptors are searched for a class. As the AJVM loads classes on demand during process540using the class loader, the dependency descriptors loaded during process520are searched for the class. In some examples, a package associated with the class may be determined. In some examples, the dependency descriptors may be searched to select a dependency descriptor associated with the class. In some examples, the dependency descriptors may be consistent with the dependency descriptors ofFIG. 1Aand/orFIG. 1B. In some examples, a package associated with the class may be used to determine the dependency descriptor associated with the class.

At the process620, information for the class is determined. Once the dependency descriptor associated with the class is determined, information for the class is determined. In some examples, the information for the class includes the dependency descriptor associated with the class. In some examples, the information for the class includes a package ID and a version for the package associated with the class. In some examples, the information for the class includes a group ID, an artifact ID, and the version for the package associated with the class. In some examples, the information associated with the class may include a class name for the class. In some examples, the information associated with the class may include an identity for a dependency cluster.

At the process630, the class is requested from a dependency cluster. Based on the information associated with the class determined during process620, a request is made to the dependency cluster (e.g., the dependency cluster350). In some examples, the request may include the dependency descriptor associated with the class. In some examples, the request may include sufficient information associated with the class to unambiguously identify the class. In some examples, the request may be transmitted to the dependency cluster. In some examples, the request may be transmitted to any dependency node (e.g., dependency node360and/or370) in the dependency cluster. In some examples, the request may be transmitted over a network (e.g., network340). In some examples, when no response to the request is received, additional requests may be made to the same and/or different dependency nodes in the dependency cluster.

At the process640, the class is received from the dependency cluster. After the request made during process630is received by the dependency cluster, the dependency cluster may locate and return a class file associated with the class to the class loader, which is then received by the class loader and/or the AJVM. In some examples, the class file may be assembled from one or more fragments by the dependency cluster. In some examples, the class file may be received from the dependency node to which the request was transmitted during process630. In some examples, when the class is not received from the dependency cluster, the class loader may generate an error and/or throw a corresponding exception.

FIG. 7is a simplified diagram of a method700for processing class requests according to some examples. As shown inFIG. 7, the method700includes a process710for receiving a class request, a process720for determining information for the class, a process730for loading fragments stored in memory, a process740for requesting fragments from other dependency nodes, a process750for assembling the class from the fragments, a process760for validating the assembled class, and a process770for returning the assembled class. According to certain examples, the method700for processing class requests can be performed using variations among the processes710-770as would be recognized by one of ordinary skill in the art. In some examples, process760is optional and may be omitted. In some examples, one or more of the processes710-770of method700may be implemented, at least in part, in the form of executable code stored on non-transient, tangible, machine readable media that when run by one or more processors (e.g., control unit362in dependency node360and/or control unit372in dependency node370) may cause the one or more processors to perform one or more of the processes710-770.

At the process710, a class request is received. In some examples, the class request may be received at a dependency node (e.g., dependency node360and/or370). In some examples, the class request may be received from a class loader and/or an AJVM (e.g., as a result of process630). In some examples, the class request may include sufficient information to identify the class. In some examples, the class request may include a dependency descriptor associated with the class.

At the process720, information for the class is determined. In some examples, the information for the class may be extracted from the class request received during process710. In some examples, the information for the class may include the dependency descriptor associated with the class. In some examples, the dependency descriptors may be consistent with the dependency descriptors ofFIG. 1Aand/orFIG. 1B. In some examples, the information for the class may be used to unambiguously identify the class.

At the process730, fragments stored in memory are loaded. In some examples, the dependency node processing the class request received during process710may load any fragments associated with the class stored in the memory (e.g., memory364and/or memory374) of the dependency node. In some examples, the fragments may be the fragments stored by the dependency node during process460. In some examples, the dependency node may determine the fragments associated with the class by matching the information for the class determined during process720with tags for each of the fragments. In some examples, when a dependency descriptor in a tag is the same as the dependency descriptor associated with the class, the corresponding fragment is associated with the class. In some examples, the dependency node may not be storing any of the fragments associated with the class and no fragments are loaded during process730.

At the process740, fragments are requested from other dependency nodes. In some examples, the dependency node processing the class request may not be storing all of the fragments associated with the class and may request any remaining fragments from the other dependency nodes in a dependency cluster. In some examples, when the dependency node is storing all of the fragments associated with the class, process740may be skipped. In some examples, the dependency node may request fragments from the other dependency nodes by transmitting further class requests similar to the class request received during process710to the other dependency nodes. In some examples, the further class request may be transmitted over a network (e.g., cluster network380). In some examples, the dependency node may request only fragments associated with the class that the dependency node is not storing. In some examples, one or more of the other dependency nodes may respond to the further class requests by returning corresponding fragments to the dependency node. In some examples, the other dependency nodes may satisfy the further class requests by recursively making further requests using process740(or a corresponding process).

At the process750, the class is assembled from the fragments. In some examples, the fragments loaded during process730and the fragments received in response to the further class requests made during process740may be assembled to form the class. In some examples, the assembled class forms a class file. In some examples, a position of each fragment in the class file may be determined based on a starting byte and/or a fragment number included in a tag associated with the respective fragment.

At the optional process760, the assembled class may be validated. In some examples, the class assembled during process750may be examined to validate that it is both complete and correct. In some examples, a total size of the assembled class may be compared to a total size included in one or more of the tags associated with the fragments. In some examples, a total number of fragments for the assembled class may be compared to a total number of fragments included in one or more of the tags associated with the fragments. In some examples, a validation code of the assembled class may be compared to a validation field included in one or more of the tags associated with the fragments. In some examples, when the assembled class is not validated, processes730-760may be repeated to assemble and revalidate the class using different fragments.

At the process770, the assembled class is returned. The class assembled during process750is returned based on the request received during process710. In some examples, the assembled class may be returned to the requesting class loader and/or AJVM. In some examples, the assembled class may be received by the requesting class loader and/or AJVM using process640. In some examples, when the assembled class may not be returned, an error response is returned. In some examples, the assembled class may not be returned when the requested class cannot be found in the dependency cluster. In some examples, the assembled class may not be returned when the assembled class does not pass validation during process760. In some examples, the assembled class may not be returned when one or more fragments associated with the class cannot be found.

According to certain examples, run-time dependency resolution may have one or more advantages. In some examples, dependencies are not resolved until a dependency is used by a project at run-time allowing execution of the project without first loading all of the classes referenced by a project. In some examples, memory on the deployment platform may be conserved because only those classes that are actually used during execution may be loaded to the deployment platform.

Some examples of a computer workstation, deployment platform310, and/or dependency nodes360and/or370may include non-transient, tangible, machine readable media that include executable code that when run by one or more processors (e.g., processor312and/or one or more processors in control unit362and/or372) may cause the one or more processors to perform the processes of methods200,400,500, and/or700as described above. Some common forms of machine readable media that may include the processes of methods200,400,500, and/or700are, for example, floppy disk, flexible disk, hard disk, magnetic tape, any other magnetic medium, CD-ROM, any other optical medium, punch cards, paper tape, any other physical medium with patterns of holes, RAM, PROM, EPROM, FLASH-EPROM, any other memory chip or cartridge, and/or any other medium from which a processor or computer is adapted to read.